qjit(fn=None, *args, compiler='catalyst', **kwargs)[source]

A decorator for just-in-time compilation of hybrid quantum programs in PennyLane.

This decorator enables both just-in-time and ahead-of-time compilation, depending on the compiler package and whether function argument type hints are provided.


Currently, only the Catalyst hybrid quantum-classical compiler is supported. The Catalyst compiler works with the JAX interface.

For more details, see the Catalyst documentation and catalyst.qjit().


Catalyst supports compiling QNodes that use lightning.qubit, lightning.kokkos, braket.local.qubit, and braket.aws.qubit devices. It does not support default.qubit.

Please see the Catalyst documentation for more details on supported devices, operations, and measurements.

  • fn (Callable) – Hybrid (quantum-classical) function to compile

  • compiler (str) – Name of the compiler to use for just-in-time compilation

  • autograph (bool) – Experimental support for automatically converting Python control flow statements to Catalyst-compatible control flow. Currently supports Python if, elif, else, and for statements. Note that this feature requires an available TensorFlow installation. See the AutoGraph guide for more information.

  • keep_intermediate (bool) – Whether or not to store the intermediate files throughout the compilation. The files are stored at the location where the Python script is called. If True, intermediate representations are available via the mlir, jaxpr, and qir, representing different stages in the optimization process.

  • verbosity (bool) – If True, the tools and flags used by Catalyst behind the scenes are printed out.

  • logfile (TextIOWrapper) – File object to write verbose messages to (default is sys.stderr)

  • pipelines (List[Tuple[str, List[str]]]) – A list of pipelines to be executed. The elements of this list are named sequences of MLIR passes to be executed. A None value (the default) results in the execution of the default pipeline. This option is considered to be used by advanced users for low-level debugging purposes.


A class that, when executed, just-in-time compiles and executes the decorated function

Return type


  • FileExistsError – Unable to create temporary directory

  • PermissionError – Problems creating temporary directory

  • OSError – Problems while creating folder for intermediate files

  • AutoGraphError – Raised if there was an issue converting the given the function(s).

  • ImportError – Raised if AutoGraph is turned on and TensorFlow could not be found.


In just-in-time (JIT) mode, the compilation is triggered at the call site the first time the quantum function is executed. For example, circuit is compiled as early as the first call.

dev = qml.device("lightning.qubit", wires=2)

def circuit(theta):
    qml.RX(theta, wires=1)
    return qml.expval(qml.PauliZ(wires=1))
>>> circuit(0.5)  # the first call, compilation occurs here
>>> circuit(0.5)  # the precompiled quantum function is called

qjit() compiled programs also support nested container types as inputs and outputs of compiled functions. This includes lists and dictionaries, as well as any data structure implementing the JAX PyTree.

dev = qml.device("lightning.qubit", wires=2)

def f(x):
    qml.RX(x["rx_param"], wires=0)
    qml.RY(x["ry_param"], wires=0)
    qml.CNOT(wires=[0, 1])
    return {
        "XY": qml.expval(qml.PauliX(0) @ qml.PauliY(1)),
        "X": qml.expval(qml.PauliX(0)),
>>> x = {"rx_param": 0.5, "ry_param": 0.54}
>>> f(x)
{'X': array(-0.75271018), 'XY': array(1.)}

For more details on using the qjit() decorator and Catalyst with PennyLane, please refer to the Catalyst quickstart guide, as well as the sharp bits and debugging tips page for an overview of the differences between Catalyst and PennyLane, and how to best structure your workflows to improve performance when using Catalyst.