PennyLane
Install
Install
  1. Blog/
  2. Releases/
  3. PennyLane v0.44 and Catalyst v0.14 released

January 13, 2026

PennyLane v0.44 and Catalyst v0.14 released

Gabriela Sanchez Diaz

Gabriela Sanchez Diaz

Isaac De Vlugt

Isaac De Vlugt

Josh Izaac

Josh Izaac

Diego Guala

Diego Guala

Anton Naim Ibrahim

Anton Naim Ibrahim

v0.44

PennyLane v0.44 and Catalyst v0.14 are here to help you solve the biggest mysteries in quantum computing ๐Ÿ•ต๏ธ

New features this release include QRAM templates, IQP circuits, Pauli-based computation functionality, resource estimation for FTQC algorithms, detailed qjit'd circuit inspection, and much more โ€” get the details down below!

A reminder as well that your feedback is key, and will help shape the future of PennyLane. Please take a moment to fill out our quantum programming survey before Thursday, February 12 โ€” weโ€™re listening!

Contents

  • Write your FTQC algorithm
    • Quantum Random Access Memory (QRAM) ๐Ÿ’พ
    • Instantaneous Quantum Polynomial Circuits ๐Ÿ’จ
  • Compile your FTQC algorithms
    • Pauli-based computation ๐Ÿ’ป
    • Flexible and modular compilation pipelines ๐Ÿฆ‹
  • Understand your FTQC algorithms
    • FTQC algorithm resource estimation ๐Ÿ“–
    • Detailed qjitโ€™d circuit inspection ๐Ÿ”Ž
  • Deprecations and breaking changes ๐Ÿ’”
  • Community contributions
  • Contributors โœ๏ธ

Write your FTQC algorithm

Write your FTQC algorithm

Quantum Random Access Memory (QRAM) ๐Ÿ’พ

Can't remember the clues? Try to stir your memory ๐Ÿค”

Three implementations of QRAM are now available in PennyLane as part of a continuing collaboration with the Yale Quantum Institute, including:

  • BBQRAM : a bucket-brigade style QRAM implementation that is also resilient to noise.
  • SelectOnlyQRAM : a QRAM implementation that comprises a series of MultiControlledX gates.
  • HybridQRAM : a QRAM implementation that combines BBQRAM and SelectOnlyQRAM in a manner that allows for tradeoffs between depth and width.

The choice of QRAM implementation depends on the application, ranging from width versus depth tradeoffs to noise resilience. For more theoretical details, check out QRAM: A Survey and Critique.

An example of using BBQRAM to read data into a target register is given below, where the data set in question is given by a list of bitstrings and we wish to read its second entry ("110"):

import pennylane as qml
import numpy as np

bitstrings = ["010", "111", "110", "000"]
bitstring_size = 3
num_control_wires = 2 # len(bistrings) = 4 = 2**2
num_work_wires = 1 + 3 * ((1 << num_control_wires) - 1) # 10

reg = qml.registers({"control": num_control_wires,
                     "target": bitstring_size,
                     "work_wires": num_work_wires})

dev = qml.device("default.qubit")
@qml.qnode(dev)
def bb_quantum():
    # prepare an address, e.g., |10> (index 2)
    qml.BasisEmbedding(2, wires=reg["control"])
    qml.BBQRAM(
        bitstrings,
        control_wires=reg["control"],
        target_wires=reg["target"],
        work_wires=reg["work_wires"],
    )
    return qml.probs(wires=reg["target"])
>>> print(np.round(bb_quantum()))  
[0. 0. 0. 0. 0. 0. 1. 0.]

Note that "110" in binary is equal to 6 in decimal, which is the position of the only non-zero entry in the target_wires register.

For more information on each implementation of QRAM in this release, check out their respective documentation pages: BBQRAM, SelectOnlyQRAM, and HybridQRAM.

Instantaneous Quantum Polynomial Circuits ๐Ÿ’จ

What if we could train quantum machine learning models on classically, and then deploy on quantum hardware? ๐Ÿคฉ We can, with IQP optimization.

A new template for defining an Instantaneous Quantum Polynomial (IQP) circuit has been added, as well as compatibility with qml.estimator.estimate for fast resource estimation. These new features facilitate the simulation and resource estimation of large-scale generative quantum machine learning tasks. For more theoretical details, check out our Fast optimization of instantaneous quantum polynomial circuits demo.

While IQP circuits are believed to be hard to sample from, their expectation values for Pauli-Z operators can be evaluated efficiently. With this PennyLane release, you can use the new qml.qnn.iqp_expval function to rapidly evaluate expectation values for circuits with thousands of qubits and millions of gates via a Monte Carlo method.

Here is a simple example showing how to define an IQP circuit, estimate the resources for its simulation, and compute the expectation values for the operators Z_1, Z_0 and Z_0 Z_1:

import pennylane as qml
import pennylane.estimator as qre
import jax

pattern= [[[0]],[[1]],[[0,1]]] # binary array representing gates X0, X1, X0X1
ops = np.array([[0, 1], [1, 0], [1, 1]]) # binary array representing ops Z1, Z0, Z0Z1
num_wires = 2
weights = np.ones(len(pattern))
n_samples = 1000
key = jax.random.PRNGKey(42)

@qml.qnode(qml.device('lightning.qubit', wires=2))
def circuit():
    qml.IQP(weights=weights, num_wires=num_wires, pattern=pattern)
    return qml.state()

expvals = qml.qnn.iqp_expval(ops, weights, pattern, num_wires, n_samples, key)[0]
>>> res = qre.estimate(circuit)()
>>> print(res)
--- Resources: ---
Total wires: 2
    algorithmic wires: 2
    allocated wires: 0
    zero state: 0
    any state: 0
Total gates : 138
    'T': 132,
    'CNOT': 2,
    'Hadamard': 4
>>> print(expvals)
[0.18971464 0.14175898 0.17152457]

Compile your FTQC algorithms

Compile your FTQC algorithms

Pauli-based computation ๐Ÿ’ป

Compiling the facts never felt this smooth ๐Ÿ˜ฎโ€๐Ÿ’จ

New tools dedicated to fault-tolerant quantum computing (FTQC) research based on the Pauli-based computation (PBC) framework are now available! With this release, you can express, compile, and inspect workflows written in terms of Pauli product rotations (PPRs) and Pauli product measurements (PPMs), which are the building blocks of the PBC framework.

Writing circuits in terms of Pauli product measurements (PPMs) in PennyLane is now possible with the new pauli_measure function. Using this function in tandem with PauliRot to represent PPRs unlocks surface-code FTQC research spurred from A Game of Surface Codes.

Using pauli_measure in a circuit is similar to measure, but requires that a pauli_word be specified for the measurement basis:

import pennylane as qml
import jax.numpy as jnp

dev = qml.device("null.qubit", wires=3)

def qfunc():
    qml.Hadamard(0)
    qml.Hadamard(2)
    qml.SWAP([0, 1])
    qml.RZ(0.1, wires=1)
    qml.PauliRot(jnp.pi / 4, pauli_word="XYZ", wires=[0, 1, 2])
    ppm = qml.pauli_measure(pauli_word="XY", wires=[0, 2])
    qml.cond(ppm, qml.X)(0)
>>> print(qml.draw(qfunc)())
0: โ”€โ”€Hโ”€โ•ญSWAPโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ญRXYZ(0.79)โ”€โ•ญโ”คโ†—Xโ”œโ”€โ”€Xโ”€โ”ค  
1: โ”€โ”€โ”€โ”€โ•ฐSWAPโ”€โ”€RZ(0.10)โ”€โ”œRXYZ(0.79)โ”€โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ•‘โ”€โ”ค  
2: โ”€โ”€Hโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฐRXYZ(0.79)โ”€โ•ฐโ”คโ†—Yโ”œโ”€โ”€โ•‘โ”€โ”ค  
                                     โ•šโ•โ•โ•โ•โ•    

Additionally, you can compile circuits expressed in terms of PPRs, PPMs, and/or Clifford+T gates with several compilation passes that are compatible with qjit (e.g., transforms.gridsynth and transforms.ppm_compilation) and inspect the results pass-by-pass with specs:

qml.capture.enable()
qml.decomposition.enable_graph()

gate_set = {qml.T, qml.S, qml.CNOT, qml.H, qml.GlobalPhase, qml.PauliRot, qml.ops.PauliMeasure}

@qml.qjit(target="mlir")
@qml.transforms.ppm_compilation
@qml.transforms.gridsynth
@qml.transforms.decompose(gate_set=gate_set)
@qml.qnode(dev)
def circuit():
    qfunc()
    return qml.expval(qml.Z(0))
>>> print(qml.specs(circuit, level=5)())
... 
Resource specifications:
  Total wire allocations: 18
  Total gates: 53
  Circuit depth: Not computed

Gate types:
  PPM: 33
  PPR-pi/2: 17
  PauliRot: 1
  qec.fabricate: 1
  GlobalPhase: 1
...

For a complete list of available compilation passes available for PBC workflows, check out the full release notes!

Flexible and modular compilation pipelines ๐Ÿฆ‹

Compile the evidence with these new features ๐Ÿง 

Defining large and complex compilation pipelines in intuitive, modular, and flexible ways is now possible with the new CompilePipeline class. CompilePipeline allows you to chain together multiple transforms to create custom circuit optimization pipelines in the following ways:

  • Compounding different CompilePipeline instances together.
  • Adding CompilePipeline instances together or multiplying by a scalar (to repeat the given pipeline an integer number of times).
  • Using list operations like append, extend, and insert.

Here is an all-encompassing example of creating a complex compilation pipeline:

>>> import pennylane as qml
>>> pipeline = qml.CompilePipeline(qml.transforms.commute_controlled, qml.transforms.cancel_inverses)
>>> pipeline = qml.CompilePipeline(pipeline, qml.transforms.merge_rotations)
>>> pipeline.extend(2 * qml.transforms.cancel_inverses(recursive=True))
>>> pipeline
CompilePipeline(commute_controlled, cancel_inverses, merge_rotations, cancel_inverses, cancel_inverses)

You can then apply a pipeline directly on a circuit as a decorator, applying each compilation pass therein:

@pipeline
@qml.qnode(qml.device("default.qubit"))
def circuit():
    qml.H(0)
    qml.H(0)

    qml.Y(1)
    qml.CRY(0.1, wires=[0, 1])
    qml.PhaseShift(0.2, wires=0)
    
    qml.RX(0.5, 1)
    qml.RX(0.2, 1)
    return qml.expval(qml.Z(0) @ qml.Z(1))
>>> print(qml.draw(circuit)())
0: โ”€โ•ญโ—โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€Rฯ•(0.20)โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ•ญ<Z@Z>
1: โ”€โ•ฐRY(0.10)โ”€โ”€Yโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€RX(0.70)โ”€โ”ค โ•ฐ<Z@Z>

Understand your FTQC algorithms

Understand your FTQC algorithms

FTQC algorithm resource estimation ๐Ÿ“–

Suspicious activity in your account? Balance the books with new resource estimation tools ๐Ÿง‘โ€๐Ÿ’ป

In the last release, we launched the estimator module for quantum resource estimation. Check out the How to use PennyLane for Resource Estimation demo to learn how estimator makes it easy to investigate which quantum programs will be worth running on upcoming FTQC hardware and which use too many qubits or gates.

In this release, we've added support for many new state-of-the-art algorithms, so you can determine which of these are the most promising for your quantum programs without spending weeks combing through research and calculations.

For example, estimate the cost of the versatile Quantum Singular Value Transformation (QSVT) algorithm in milliseconds using a light-weight operator that only requires a few simple inputs:

import pennylane.estimator as qre
block_encoding = qre.MultiRZ(wires=range(1000))
qsvt = qre.QSVT(block_encoding, encoding_dims=(2, 2), poly_deg=10**10)
>>> print(qre.estimate(qsvt))
--- Resources: ---
 Total wires: 1997
   algorithmic wires: 1000
   allocated wires: 997
     zero state: 997
     any state: 0
 Total gates : 1.613E+14
   'Toffoli': 1.994E+13,
   'T': 1.760E+12,
   'CNOT': 3.992E+13,
   'X': 3.994E+13,
   'Hadamard': 5.976E+13

It's also easy to fully define a quantum program, verify its output via simulation, and then swap to resource estimation to determine its cost or scale up.

First we define the quantum program:

import numpy as np
poly = [0, -1, 0, 0.5, 0, 0.5]
hamiltonian = qml.dot([0.3, 0.7], [qml.Z(1), qml.X(1) @ qml.Z(2)])

dev = qml.device("lightning.qubit")
@qml.qnode(dev)
def circuit():
    qml.qsvt(hamiltonian, poly, encoding_wires=[0], block_encoding="prepselprep")
    return qml.probs()

Then we simulate:

>>> print(circuit())
[0.14483425 0.         0.78854205 0.         0.03331185 0.
0.03331185 0.        ]

And we easily obtain qubit and gate counts using qre.estimate:

>>> print(qre.estimate(circuit)())
--- Resources: ---
 Total wires: 3
   algorithmic wires: 3
   allocated wires: 0
     zero state: 0
     any state: 0
 Total gates : 1.219E+3
   'Toffoli': 5,
   'T': 1.144E+3,
   'CNOT': 25,
   'X': 10,
   'Hadamard': 35

Other new algorithms include qre.Qubitization, qre.QSP, and qre.UnaryIterationQPE. See the v0.44 release notes for a full list of new algorithms.

Finally, you can compute algorithm-specific errors from quantum circuits with a new algo_error function. This provides a dedicated entry point for retrieving error information that was previously accessible through specs.

The function works with QNodes and returns a dictionary of error types and their computed values:

import pennylane as qml

Hamiltonian = qml.dot([1.0, 0.5], [qml.X(0), qml.Y(0)])

dev = qml.device("default.qubit")

@qml.qnode(dev)
def circuit():
    qml.TrotterProduct(Hamiltonian, time=1.0, n=4, order=2)
    return qml.state()
>>> qml.resource.algo_error(circuit)()
{'SpectralNormError': SpectralNormError(0.25)}

Detailed qjitโ€™d circuit inspection ๐Ÿ”Ž

Don't be afraid to get your hands dirty... get your rubber gloves on and understand what's inside your qjit'd circuits with our new inspection tools ๐Ÿ”ฌ

Analyzing resources throughout each step of a compilation pipeline can now be done for qjit'd workflows using the new and improved specs function, providing a pass-by-pass overview of quantum circuit resources.

Consider the following qjit'd circuit with two compilation passes applied:

import pennylane as qml

@qml.qjit
@qml.transforms.merge_rotations
@qml.transforms.cancel_inverses
@qml.qnode(qml.device('lightning.qubit', wires=2))
def circuit():
    qml.RX(1.23, wires=0)
    qml.RX(3.45, wires=0)
    qml.RY(6.78, wires=1)
    qml.X(0)
    qml.X(0)
    qml.CNOT([0, 1])
    return qml.probs()

The supplied level to specs can be an individual int value or an iterable of multiple levels. Additionally, consider the strings "all" and "all-mlir" to receive circuit resources for all user-applied transforms and MLIR passes, or specifically user-applied MLIR passes, respectively.

>>> qml.specs(circuit, level=3)()
Device: lightning.qubit
Device wires: 2
Shots: Shots(total=None)
Level: 3

Resource specifications:
  Total wire allocations: 2
  Total gates: 3
  Circuit depth: Not computed

  Gate types:
    RX: 1
    RY: 1
    CNOT: 1

  Measurements:
    probs(all wires): 1

Resources are one thing, the logic of an algorithm another โ€” use the new catalyst.draw_graph to see your dynamic qjit'd circuits visualized as graphs.

Let's visualize a structured circuit using catalyst.draw_graph, which also allows you to provide a level corresponding to the stage of compilation at which you would like to visualize your program!

import pennylane as qml
import catalyst

qml.capture.enable()

@qml.qjit(autograph=True)
@qml.transforms.cancel_inverses
@qml.transforms.merge_rotations
@qml.qnode(qml.device("null.qubit", wires=3))
def circuit(x, y):
    qml.X(0)
    qml.Y(1)
    qml.H(x)
    for i in range(3):
        qml.S(0)
        qml.RX(0.1, wires=1)
        qml.RX(0.2, wires=1)
        qml.RX(0.2, wires=2)
        if i == 3:
            qml.T(0)
        else:
            qml.H(0)
            qml.H(0)
    
    return qml.expval(qml.Z(y))
>>> fig, ax = catalyst.draw_graph(circuit, level=2)(1,2)
>>> fig.savefig('path_to_file.png', dpi=200, bbox_inches="tight")
Graph visualization of circuit

Notice how we're able to see the structure of the program even after we've made optimizations using the compilation passes!

Deprecations and breaking changes ๐Ÿ’”

As new things are added, outdated features are removed. To keep track of things in the deprecation pipeline, check out the deprecations page.

Here's a summary of what has changed in this release:

  • Maintenance support of NumPy<2.0 is deprecated as of v0.44 and will be completely dropped in v0.45. Future versions of PennyLane will only work with NumPy>=2.0. We recommend upgrading your version of NumPy to benefit from enhanced support and features.
  • The custom_decomps keyword argument to pennylane.device has been deprecated and will be removed in 0.45. Instead, with decomposition.enable_graph, new decomposition rules can be defined as quantum functions with registered resources. See pennylane.decomposition for more details.
  • The value level=None is no longer a valid argument in the following: workflow.get_transform_program, workflow.construct_batch, drawer.draw, drawer.draw_mpl, and specs. Please use level='device' instead to apply all transforms.
  • QuantumScript.to_openqasm has been removed. Please use to_openqasm instead. This removes duplicated functionality for converting a circuit to OpenQASM code.

These highlights are just scratching the surface โ€” check out the full release notes for PennyLane and Catalyst for more details.

And don't forget to let your voice be heard by taking a few minutes to fill out our quantum programming survey before Thursday, February 12, to help shape future PennyLane development.

Community contributions

In this release cycle we merged 12 PRs from a number of community contributors (with some still in the pipeline for the next release!): Shifan Xu, Dantong Li, and โ€‹โ€‹Roberto Turrado Camblor.

Thank you for your contributions! ๐Ÿ™

Contributors โœ๏ธ

As always, this release would not have been possible without the hard work of our development team and contributors:

Runor Agbaire, Guillermo Alonso, Utkarsh Azad,ย  Joseph Bowles, Astral Cai, Yushao Chen, Isaac De Vlugt, Diksha Dhawan, Marcus Edwards, Tarik El-Khateeb, Ashley Enman, Lillian Frederiksen, Sengthai Heng, Austin Huang, David Ittah, Soran Jahangiri, Jeffrey Kam, Jacob Kitchen, Christina Lee, Joseph Lee, Lee J. O'Riordan, Gabriela Sanchez Diaz, Mudit Pandey, Shuli Shu, Jay Soni, Nate Stemen, Theodoros Trochatos, David Wierichs, Shifan Xu, Hongsheng Zheng, Zinan Zhou, Diego Guala, Anton Naim Ibrahim, David Ittah, Korbinian Kottmann, Ali Asadi, Joey Carter, Mehrdad Malekmohammadi, River McCubbin, Mudit Pandey, Andrija Paurevic, Roberto Turrado, Luis Alfredo Nuรฑez Meneses, Paul Haochen Wang, and Jake Zaia.

About the authors

Gabriela Sanchez Diaz
Gabriela Sanchez Diaz

Gabriela Sanchez Diaz

Isaac De Vlugt
Isaac De Vlugt

Isaac De Vlugt

My job is to help manage the PennyLane and Catalyst feature roadmap... and spam lots of emojis in the chat ๐Ÿค 

Josh Izaac
Josh Izaac

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.

Diego Guala
Diego Guala

Diego Guala

Diego is a quantum scientist at Xanadu. His work is focused on supporting the development of the datasets service and PennyLane features.

Anton Naim Ibrahim
Anton Naim Ibrahim

Anton Naim Ibrahim

Physicist and Technical Product Manager. Exploring uncharted territory.

Last modified:ย January 13, 2026

Related Blog Posts

PennyLane

PennyLane is a cross-platform Python library for quantum computing, quantum machine learning, and quantum chemistry. Built by researchers, for research. Created with โค๏ธ by Xanadu.

Research

  • Research
  • Performance
  • Hardware & Simulators
  • Demos
  • Quantum Compilation
  • Quantum Datasets

Education

  • Teach
  • Learn
  • Codebook
  • Coding Challenges
  • Videos
  • Glossary

Software

  • Install PennyLane
  • Features
  • Documentation
  • Catalyst Compilation Docs
  • Development Guide
  • API
  • GitHub
Stay updated with our newsletter

ยฉ Copyright 2026 | Xanadu | All rights reserved

TensorFlow, the TensorFlow logo and any related marks are trademarks of Google Inc.

Privacy Policy|Terms of Service|Cookie Policy|Code of Conduct