November 12, 2024
Demonstrating quantitative advantage with quantum just-in-time compilation and PennyLane
Over the past two years, we have been sharing details about Catalyst, our quantum just-in-time (QJIT) compiler for PennyLane — able to take your hybrid quantum-classical programs, and efficiently compile and execute them for significant speedups.

But why is QJIT compilation so valuable in practice? When does it make sense to use it, and what advantages does it give? Today, we want to showcase some of the clear, quantitative advantages of this approach, and highlight how it enables next-generation algorithm development.
Contents
- Optimize algorithms without sacrificing structure
- Compiling parametric workflows
- Try Catalyst and get involved
Optimize algorithms without sacrificing structure
Quantum algorithms, without exception, have structure. This is an important part of their design,
and we implicitly take this into account when coding them up — using for
loops and if
statements
helps us translate these algorithms compactly into software.
So why do so many compilers ignore this structure?
If we ignore this structure — unrolling for loops, and ending up with a potentially long list of gates — then program size grows significantly as we scale up our algorithm, and compilation time blows up.
Catalyst, on the other hand, performs quantum optimization while preserving control structure, resulting in constant overhead, that doesn't increase at all:

In this simple example, we've constructed a simple circuit consisting of a for loop (repeated N times) over two Hadamard gates and two RX gates:
import pennylane as qml dev = qml.device("lightning.qubit", wires=2) @qjit(autograph=True) @qml.qnode(dev) def circuit(x: float, y: float, N: int): for i in range(N): qml.Hadamard(wires=0) qml.Hadamard(wires=0) qml.RX(x, wires=1) qml.RX(y, wires=1) return qml.probs(wires=[0, 1])
The @qjit
decorator indicates that this should be compiled with Catalyst, with
Autograph used to automatically capture and preserve the for loop information.
We're then timing the application of two simple quantum optimizations: cancellation of consecutive adjoint gates, and merging of rotation gates.

In the case of the PennyLane example, we aren't applying quantum just-in-time compilation, and can
see that the compilation time scales quite badly, leading to almost 100 seconds needed to optimize
this (quite simple!) program. Whereas for the Catalyst version (where @qjit
is applied)
optimization is constant, no matter the value of N.
Wait, I hear you say. This is quite a contrived example, how does this look for real, meaningful algorithms? Good question! We repeated this experiment with an implementation of Shor's algorithm:

Again, by compiling with Catalyst and compiling the structure, there is no increase to the compilation time, even as the integer input to Shor's (and thus the program size) increases.
Compiling parametric workflows
Another area where Catalyst excels is in speeding up the execution time of hybrid quantum-classical parametric workflows (for example, workflows where we might be executing the same circuit many times with different parameters).
A great representative example of this is the variational quantum eigensolver (VQE), which involves a classical optimization loop over a circuit that is called repeatedly with different parameter values:

In this example, we get up to a 20x overall execution speedup of the VQE workflow when using quantum just-in-time compilation to compile the entire workflow (including the optimization for loop!). This allows us to continue coding up complex hybrid workflows in Python, allowing rapid prototyping, without sacrificing performance.
Under the hood, Catalyst is capturing the Python program, and compiling the program only once. We can then repeatedly call this already optimized machine binary with different input parameters — allowing us to frontload compilation and escape the slowdowns of Python in one go.
The best part? Catalyst is designed to be accessible. In most cases,
the @qjit
decorator can be added with minimal syntax changes of an existing PennyLane
program.
For more details, see our demonstration on how to quantum just-in-time compile VQE with Catalyst.
As we continue to build out Catalyst, we will also be working hard to build out the compiler stack, including native support for a wide range of common quantum compilation routines, and an API for providing or writing Catalyst-compatible compilation routines.
However, we still have much to learn! Most quantum compilation passes available in the literature apply to flat, unrolled, lists of quantum gates, and significant work needs to be done to update them to work on structured programs.
If you are interested in contributing quantum compilation routines, or trying out Catalyst, please get in touch.
Try Catalyst and get involved
Ready to explore the power of Catalyst JIT compiler with PennyLane? Start with our quick-start guide and check out the examples and tutorials in our PennyLane documentation. For an introduction to quantum computing and quantum programming, you can also visit the PennyLane website for tutorials and demonstrations.
Interested in getting in touch and collaborating with us? Simply head over to our GitHub repository, check out the ongoing work, and join the discussion and development.
And if you are as excited as we are, make sure to keep an eye on the PennyLane Blog and follow us on X (Twitter) and LinkedIn for the latest PennyLane and Catalyst updates.
About the authors
Josh Izaac
Josh is a theoretical physicist, software tinkerer, and occasional baker. At Xanadu, he contributes to the development and growth of Xanadu’s open-source quantum software products.
Paul Wang
Catalyst developer. Compilers do magical things!
Joey Carter
Joey is a quantum software developer at Xanadu. Prior to joining Xanadu, Joey completed his PhD in experimental high-energy physics at the University of Toronto.
David Ittah
Technical Lead of Compilation at Xanadu