Articles
Published:

pennylane-maestro: Faster PennyLane Simulation with a Direct Path to Hardware

pennylane qoro simulation

If you write PennyLane circuits, you likely start with default.qubit. It is the workhorse of quantum algorithm prototyping—intuitive, impeccably documented, and reliable. But as a pure Python statevector simulator, it comes with a strict physical ceiling. By 26 qubits, it exhausts available memory, and optimization loops become frustratingly sluggish well before you reach that limit.

Today, we are releasing pennylane-maestro, an open-source, drop-in PennyLane device backed by Qoro’s Maestro quantum execution engine. With a single-line code swap, it unlocks substantially faster statevector execution for small circuits, enables 50+ qubit simulations via Matrix Product States (MPS), and provides a seamless path from research code directly to real quantum hardware.

Most importantly: you do not have to rewrite a single line of your circuit logic.

# Before
dev = qml.device("default.qubit", wires=n_qubits)

# After — the rest of your code stays exactly the same
dev = qml.device("maestro.qubit", wires=n_qubits)

What Does pennylane-maestro Bring?

1. Faster execution, even as a statevector

Maestro’s default statevector backend is implemented in highly optimized C++ and runs on your existing hardware without any complex configuration. To measure the impact, we benchmarked a 2-layer hardware-efficient ansatz (HEA) VQE cost function evaluation—the standard qml.expval call inside a typical optimization loop—against both default.qubit and PennyLane’s compiled lightning.qubit:

Qubitsdefault.qubitlightning.qubitmaestro.qubit (statevector)
103 ms1 ms2 ms
147 ms3 ms8 ms
1841 ms28 ms25 ms
201.53 s126 ms82 ms
226.92 s578 ms319 ms
2421.65 s2.58 s1.41 s

At small qubit counts, Lightning’s C++ backend is undeniably fast. But as the state space expands beyond 18 qubits, Maestro’s memory management pulls ahead. By 24 qubits, Maestro is 1.8× faster than Lightning and 15× faster than default.qubit.

Beyond 26 qubits, every exact statevector backends begin to hit a fundamental memory wall. That is where tensor networks take over.

2. Five simulation modes, one interface

As quantum circuits scale, no single classical method works universally. To abstract away this engineering complexity, maestro.qubit exposes five distinct simulation algorithms, all governed by a single simulation_type parameter:

# Default: Fast C++ statevector
dev = qml.device("maestro.qubit", wires=20)

# MPS: For large-scale bounded-entanglement circuits
dev = qml.device("maestro.qubit", wires=100,
                 simulation_type="MatrixProductState",
                 max_bond_dimension=64)

# Stabilizer: For 1000+ qubit Clifford circuits
dev = qml.device("maestro.qubit", wires=1000,
                 simulation_type="Stabilizer") # or PauliPropagator

# GPU: Hardware-accelerated statevector
dev = qml.device("maestro.qubit", wires=30,
                 simulator_type="Gpu")

The available modes include Statevector, MatrixProductState, Stabilizer, TensorNetwork, and PauliPropagator. You can swap between them via the standard PennyLane interface, meaning your circuit definition and optimizer remain entirely untouched, all of which also work on GPU (See: maestro.qoroquantum.net).

3. MPS with native shot sampling

The MPS mode is what breaks the ~26-qubit barrier, enabling 50+ qubit research on standard hardware. For systems exhibiting bounded entanglement—such as spin chains, lattice models, and many VQE ansätze with local structure—MPS is the computationally correct tool. It delivers accurate expectation values at a fraction of the memory footprint of a full statevector.

What makes Maestro’s implementation distinct is its native support for shot-based sampling directly on MPS states, a critical feature largely absent in other PennyLane MPS backends. If your workflow relies on bitstring statistics—such as computing a magnetization order parameter or sampling to estimate entropy—it works on maestro.qubit exactly as it would on default.qubit:

dev = qml.device("maestro.qubit", wires=50,
                 simulation_type="MatrixProductState",
                 max_bond_dimension=64,
                 shots=10_000)  # Natively supported

To put a number on the MPS speedup: the exact same 30-qubit VQE gradient step ran in 0.53 s on maestro.qubit compared to 19.2 s on PennyLane’s native default.tensor backend. That is a 36× speedup, yielding numerically identical results. In practice, a 36× difference fundamentally changes the research cadence. A typical VQE optimization loop of 100 gradient steps that would take over half an hour on standard tensor backends completes in under a minute with Maestro.

A Concrete Walkthrough: Research to Hardware

To demonstrate a real-world quantum workflow, we implemented a 30-qubit Variational Quantum Eigensolver (VQE) targeting the ground state of the 1D transverse-field Ising model (TFIM).

H = −J Σ ZᵢZᵢ₊₁ − h Σ Xᵢ (J = h = 1.0)

With a theoretical baseline of E₀ = −37.84, we used a 120-parameter hardware-efficient ansatz to test a three-stage development lifecycle:

1. Research & Idealized Simulation (PennyLane + Maestro)

We begin in PennyLane, using the Maestro engine to leverage gradient-based optimizers. This phase allows us to rapidly iterate on circuit design and verify the algorithm’s “best-case” performance in an analytical environment.

2. Hardware Mimicry (Divi + Solo Simulation)

Transitioning toward real-world deployment, we use Divi and Solo, Qoro’s cloud simulation engine. Here, we introduce “shot noise” to mimic the probabilistic nature of real hardware, where standard gradient-based methods often struggle.

3. Resource Optimization & Execution (Divi + Solo Hardware)

Finally, we move to Hardware, running on IBM quantum computers. To handle the constraints of physical QPUs, we swap to population-based optimization and utilize observable grouping to minimize the number of circuits needed. This stage provides a seamless transition from simulation to HPC or quantum hardware with a single parameter change.

Stage 1: Local Research (PennyLane + Maestro MPS)

dev = qml.device("maestro.qubit", wires=n_qubits,
                 simulation_type="MatrixProductState",
                 max_bond_dimension=64)

@qml.qnode(dev)
def cost_fn(params):
    hardware_efficient_ansatz(params, wires=range(n_qubits))
    return qml.expval(hamiltonian)

opt = qml.MomentumOptimizer(stepsize=0.05)
for step in range(30):
    params, energy = opt.step_and_cost(cost_fn, params)

In just 15.6 seconds, 30 gradient steps yielded an energy of −32.03. Because the 1D TFIM ground state adheres to an area law (bounded entanglement), utilizing MPS at a bond dimension of 64 provides high accuracy—it is not a crude approximation.

At the end of Stage 1, we checkpoint the parameters and Stages 2 and 3 load directly from this checkpoint, saving expensive QPU time by pre-training the parameters, allowing you to iterate with hardware runs without needing to start the optimization process from scratch.

Stage 2: Validation on Divi + Solo Simulation

With gradient convergence achieved in an ideal environment, the next step is validating those parameters under realistic shot noise before expending valuable QPU time. Here, we transition to Qoro Divi’s MonteCarloOptimizer. It is shot-native, gradient-free, and designed to execute identically across cloud simulators and physical hardware.

from divi import MonteCarloOptimizer
from divi.backends import QoroService
from divi.backends.config import JobConfig

backend = QoroService(
    job_config=JobConfig(
        simulator_cluster="qoro_maestro",
        shots=10_000,
    )
)

optimizer = MonteCarloOptimizer(hamiltonian=hamiltonian, ansatz=ansatz,
                                n_params=n_params, population_size=20)
result = optimizer.run(backend, n_iterations=3, initial_params=stage1_params)

In 3 Monte Carlo iterations (11.1 seconds end-to-end), we successfully validated the energy at −32.03. By seeding the MC population with the Stage 1 parameters, this acts as a rapid validation step rather than a cold-start optimization.

The shift in optimizers is an engineering necessity: parameter-shift gradients are prohibitively expensive on hardware (costing 2N circuit executions per step) and degrade rapidly under shot noise. Population-based Monte Carlo is natively resilient to noise and maps perfectly to QPU execution.

Stage 3: Real Hardware Execution (IBM QPU)

To move from the cloud simulator to real superconducting qubits, exactly one configuration field changes:

backend = QoroService(
    job_config=JobConfig(
        qpu_system="superconducting_qpus",   # Transitioned from "qoro_maestro"
        shots=10_000,
    )
)

Everything else remains identical. The optimizer code from Stage 2 executes unmodified on an IBM superconducting QPU.

After 4 MC iterations on hardware, the QPU energies settled around −22.4. The delta between the cloud result (−32.03) and the QPU result is the stark reality of hardware noise—gate infidelities, readout errors, and decoherence. You can see this transition clearly in the plot above.

A Note on Circuit Packing: We also executed this stage with Divi’s circuit packing enabled via a single flag in JobConfig. The same 80 circuits that took 54 seconds per job unpacked completed in just 21 seconds per job when packed into optimized payloads. The resulting energies were statistically identical. For iterative algorithms requiring dozens of QPU calls, this compounds into a massive reduction in wall-clock time and compute budget.

The Core Philosophy

Our architecture is built on three design principles that bridge the gap between theoretical research and hardware reality.

1. The Gradient → Monte Carlo Handoff

Efficiency in simulation, resilience on hardware. Gradient optimizers are excellent for the “sprint” in ideal simulations, but they often stumble over hardware noise and execution costs. We use gradients to find the neighborhood of the solution quickly, then “warm-start” a Monte Carlo optimizer for the final refinement. This provides rapid convergence where it’s cheap and shot-native robustness where it matters.

2. Targeted MPS Application

The right mathematical tool for the geometry. We don’t treat every circuit like a black box. While Matrix Product States (MPS) aren’t a universal fix for deep entanglement, they are the mathematically “correct” choice for 1D spin chains and lattice models. For these locally structured ansätze, MPS isn’t an approximation—it’s a fundamentally more efficient way to represent the quantum state.

3. Configuration Over Code

Logic is permanent; hardware is temporary. A researcher’s time should be spent on the algorithm, not the infrastructure. Whether you are switching from a CPU statevector to GPU acceleration or moving from an MPS simulation to a physical QPU, it should be a single parameter swap. By decoupling the circuit definition from the execution environment, we let the method adapt to the problem—not the other way around.

Ultimately, we’re building a bridge from the whiteboard to the wire, ensuring that the move to real-scale execution in HPC and on quantum hardware is a strategic evolution, not a technical overhaul.

Get Started

pip install pennylane-maestro

Stages 1 and 2 can run locally on your laptop. Stage 3 requires QPU access via Qoro Cloud. If you’re ready to deploy your workloads on real hardware, get in touch with our team.

To provide the best experience, we use technologies like cookies to store and/or access device information. You can manage your preferences here.