Skip to main content

PennyLane pure- and mixed-state simulator built on Metal 4

Project description

PennyLane Metal

PyPI version License CI

metal.qubit is a PennyLane quantum simulator built exclusively on Metal 4. Pure circuits use a state vector while noisy circuits use an independent density-matrix execution model. Both consume the same quantum IR and metallib; state evolution, channels, measurements, and sampling are implemented in Metal Shading Language.

Requirements

  • macOS 26.0 or newer on Apple silicon
  • A Metal 4-capable Apple GPU (M1 or newer)
  • Python 3.10–3.14

There is no Metal 3 path and no earlier macOS deployment target.

Installation

pip install pennylane-metal

Binary wheels are published for macOS 26+ (arm64) and CPython 3.10–3.14.

Building from source

Building from the sdist or a git checkout additionally requires:

  • Xcode 26 with the Metal Toolchain component
  • CMake 3.24 or newer

Install the optional Xcode component if xcrun --toolchain Metal --find metal fails:

xcodebuild -downloadComponent MetalToolchain

Then:

pip install .                # or: pip install -e '.[dev]' for development

Usage

import pennylane as qml

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

@qml.qnode(dev)
def bell_state():
    qml.H(0)
    qml.CNOT([0, 1])
    return qml.probs(wires=[0, 1])

print(bell_state())  # [0.5, 0.0, 0.0, 0.5]

The default memory_budget="auto" policy admits an execution only when its estimated peak fits within 80% of Metal's recommended working set. An explicit byte count applies a custom budget; memory_budget=None disables only this soft budget and still enforces kernel addressing and maxBufferLength:

from pennylane.tape import QuantumScript
from pennylane_metal import max_supported_qubits

dev = qml.device("metal.qubit", wires=12, memory_budget="auto")
tape = QuantumScript([], [qml.probs(wires=[0])])

print(max_supported_qubits("density_matrix"))
print(dev.estimate_resources(tape).peak_metal_bytes)
dev.release_resources()

estimate_resources accepts an already-preprocessed QuantumScript, matching the objects passed by PennyLane to execute. The low-level MetalSimulator.estimate_batch_resources(program, batch_count) API exposes the nine-slot native-batch plan; assess_resources accepts both scalar and batch estimates.

PennyLane decomposes only operations outside the native IR. The native set includes common one-qubit gates, Rot, U2, U3, CNOT/CZ/SWAP, CRot/CRX/CRY/CRZ, iSWAP/SISWAP/PSWAP/ECR, Toffoli and multi-controlled X, Ising interactions, MultiRZ, PauliRot, the single- and double-excitation families, FermionicSWAP, OrbitalRotation, state preparation, and arbitrary dense or diagonal unitaries. Hermitian and projector observables are diagonalized into the same IR. SparseHamiltonian remains CSR and is applied directly by a Metal sparse expectation kernel.

Analytic state, reduced density matrix, probability, expectation, variance, purity, von Neumann entropy, and mutual information measurements are supported. Metal computes the reduced density matrices; entropy eigenvalues are classical spectral postprocessing through macOS Accelerate. Finite-shot probability, expectation, variance, sample, and counts measurements use Metal sampling. Parameter broadcasting is expanded into scalar quantum programs; homogeneous pure-state batches containing analytic expectation or variance measurements then execute as one native batched Metal state buffer. Each simulator retains a fixed-role batch workspace, so a warmed compatible batch performs no workspace-buffer allocations and smaller batches preserve the high water mark. Mixed-state, finite-shot, state-preparation, heterogeneous-topology, and other measurement batches retain the scalar fallback. Mid-circuit measurements, reset, postselection, and classical conditionals are rejected explicitly.

Noisy circuits support QubitDensityMatrix, arbitrary multi-wire QubitChannel Kraus maps, PauliError, BitFlip, PhaseFlip, DepolarizingChannel, AmplitudeDamping, GeneralizedAmplitudeDamping, PhaseDamping, ThermalRelaxationError, and ResetError. The density-matrix model is selected internally and never routes state evolution through a CPU simulator. Density inputs are checked for Hermiticity, trace, and positive semidefiniteness without a qubit-count shortcut.

Analytic expectation values support native Metal adjoint Jacobians and VJPs for the native parameterized pure-state gates, including multi-parameter Rot/U2/U3/CRot, Ising interactions, MultiRZ, PauliRot, PSWAP, excitation gates, FermionicSWAP, and OrbitalRotation. The reverse pass, analytic gate derivatives, and parallel reductions run in Metal. Noisy circuits use PennyLane parameter-shift or finite differences, with every forward evaluation remaining on the Metal density-matrix path.

The device keeps a bounded topology-template cache and refreshes only runtime parameters, matrices, eigenvalues, sparse values, shots, and seeds on a hit. Metal precomputes local gate matrices, fuses consecutive one-qubit gates on the same wire for forward evolution, reuses adjoint workspaces, and builds large sampling CDFs with a hierarchical parallel scan. These scheduling details are internal and do not change PennyLane's execution or differentiation protocols.

Architecture

PennyLane QuantumScript
        |
        v
Python compiler: validate, decompose, map wires
        |
        v
QuantumProgram IR: opcodes, wires, parameters, measurements
        |
        v
SimulationResources: peak memory plan and device admission
        |
        v
MetalProgramBuffers
        |
        +--> MetalSimulator (pure state)
        |
        +--> MetalDensitySimulator (mixed state)
        |
        v
MetalContext
        |
        v
MTL4CommandQueue / MTL4CommandBuffer / MTL4ArgumentTable
        |
        v
Metal 4 kernels: evolution, measurement, sampling, adjoint/VJP

There is one device, one IR, and one shader library. Pure and mixed execution models are internal numerical strategies, not public backend variants. Tile, batch, and standard are not public backend classes; future scheduling strategies belong inside the runtime. Application-specific QNN layers, image patches, classifiers, optimizers, and training tapes are intentionally outside this repository.

See docs/ARCHITECTURE.md for the detailed ownership and data-flow rules.

Development

cmake -S . -B build \
  -DCMAKE_PREFIX_PATH="$PWD/.venv/lib/python3.10/site-packages" \
  -DPython_EXECUTABLE="$PWD/.venv/bin/python"
cmake --build build -j
.venv/bin/pytest

Run the full suite with Metal API Validation enabled after changing command encoding, argument bindings, or residency management. The environment variable must be set before Python initializes Metal:

MTL_DEBUG_LAYER=1 NSUnbufferedIO=YES .venv/bin/pytest

Benchmarks

The benchmark runner contains a small set of representative end-to-end comparisons rather than one case per operation:

# Common RY/RZ/CNOT workload against lightning.qubit
.venv/bin/python benchmarks/benchmark_metal.py --suite statevector

# Adjoint Jacobian for an RX/RY/CNOT workload against lightning.qubit
.venv/bin/python benchmarks/benchmark_metal.py --suite adjoint

# Native Rot and DoubleExcitation against their explicit Metal decompositions
.venv/bin/python benchmarks/benchmark_metal.py --suite native-gates

# Thermal-relaxation density evolution against default.mixed
.venv/bin/python benchmarks/benchmark_metal.py --suite density

# CSR SparseHamiltonian expectation against lightning.qubit
.venv/bin/python benchmarks/benchmark_metal.py --suite sparse

Use --suite all --iterations 5 for a short representative sweep. Individual suites accept --qubits, --depth, --iterations, and --warmups overrides. State-vector, adjoint, and sparse suites use lightning.qubit as the default reference; select --reference default.qubit or --reference none when needed. Reported times include PennyLane preprocessing, IR compilation, command encoding, GPU execution, synchronization, and result formatting.

The simulator uses complex64 storage and two ping-pong state buffers. There is no fixed product-level qubit limit: admission is calculated from the kernel address width, the current device's maxBufferLength, the selected memory budget, program scratch space, shots, and measurement output. State-vector storage scales as 2**n; density-matrix storage scales as 4**n and is normally memory-bound much earlier. Density evolution uses a two-dimensional row/column grid with 64-bit linear addresses, so it is not restricted by the old 32-bit flattened-grid boundary at 15 qubits.

Resource failures are raised as MetalResourceError by the low-level runtime and translated to PennyLane DeviceError by MetalQubit. The error names the limiting resource and reports the estimated peak and configured budget.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pennylane_metal-0.2.0.tar.gz (120.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pennylane_metal-0.2.0-cp314-cp314-macosx_26_0_arm64.whl (413.0 kB view details)

Uploaded CPython 3.14macOS 26.0+ ARM64

pennylane_metal-0.2.0-cp313-cp313-macosx_26_0_arm64.whl (412.5 kB view details)

Uploaded CPython 3.13macOS 26.0+ ARM64

pennylane_metal-0.2.0-cp312-cp312-macosx_26_0_arm64.whl (412.5 kB view details)

Uploaded CPython 3.12macOS 26.0+ ARM64

pennylane_metal-0.2.0-cp311-cp311-macosx_26_0_arm64.whl (410.3 kB view details)

Uploaded CPython 3.11macOS 26.0+ ARM64

pennylane_metal-0.2.0-cp310-cp310-macosx_26_0_arm64.whl (408.6 kB view details)

Uploaded CPython 3.10macOS 26.0+ ARM64

File details

Details for the file pennylane_metal-0.2.0.tar.gz.

File metadata

  • Download URL: pennylane_metal-0.2.0.tar.gz
  • Upload date:
  • Size: 120.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pennylane_metal-0.2.0.tar.gz
Algorithm Hash digest
SHA256 409375b8605604d02fadc082f6e0f0ff66e55e3bed2c628146037db816774d49
MD5 62a68195a91ab8eb599403ff98b6da23
BLAKE2b-256 18712d8df2abc8dd5cf76fc1e8cd57973a22ccd02211276d0f69ad7bb31526f5

See more details on using hashes here.

Provenance

The following attestation bundles were made for pennylane_metal-0.2.0.tar.gz:

Publisher: wheels.yml on dereklei12/pennylane-metal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pennylane_metal-0.2.0-cp314-cp314-macosx_26_0_arm64.whl.

File metadata

File hashes

Hashes for pennylane_metal-0.2.0-cp314-cp314-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 5029a37d4987a6850d728f3e6929b23cf95cdb907e4fe286118c74c7cef19011
MD5 3975424b277854357c0bc5aaaddbf99f
BLAKE2b-256 acff082b12bed43da4416531786a58affe75e9444a1ce907aa05f896637bb74f

See more details on using hashes here.

Provenance

The following attestation bundles were made for pennylane_metal-0.2.0-cp314-cp314-macosx_26_0_arm64.whl:

Publisher: wheels.yml on dereklei12/pennylane-metal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pennylane_metal-0.2.0-cp313-cp313-macosx_26_0_arm64.whl.

File metadata

File hashes

Hashes for pennylane_metal-0.2.0-cp313-cp313-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 821d41b74092b29f8ec6b3b6561d4c16d80a85e663878d809a4f882f36fc3069
MD5 26e90e87723cabc7ccdc7e356577e520
BLAKE2b-256 15ad69c070b08e4cded27f2f9ba06db12f16126b65b3644e50edb923701f4c4e

See more details on using hashes here.

Provenance

The following attestation bundles were made for pennylane_metal-0.2.0-cp313-cp313-macosx_26_0_arm64.whl:

Publisher: wheels.yml on dereklei12/pennylane-metal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pennylane_metal-0.2.0-cp312-cp312-macosx_26_0_arm64.whl.

File metadata

File hashes

Hashes for pennylane_metal-0.2.0-cp312-cp312-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 9c4e2f4aa4164f342ce6b0715222cc819860e62e6ce6f76149039e409298d432
MD5 91cc93e08b5a91f3f14f19e6ea377422
BLAKE2b-256 eded6ef41da45a73054d7f2df900be8ca5bb0e49333f14869d890fb0e0da81e1

See more details on using hashes here.

Provenance

The following attestation bundles were made for pennylane_metal-0.2.0-cp312-cp312-macosx_26_0_arm64.whl:

Publisher: wheels.yml on dereklei12/pennylane-metal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pennylane_metal-0.2.0-cp311-cp311-macosx_26_0_arm64.whl.

File metadata

File hashes

Hashes for pennylane_metal-0.2.0-cp311-cp311-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 45810880f974d7c2234a44ec97b0396f3fe4e15a78101b4c9bc5e7df28e6cc34
MD5 475d5267bc93c74e795a63da84c7671c
BLAKE2b-256 b7f2969a83adcb7028ebdda162828b930a4e16ba01cc3ba3788c62aeffa8c06d

See more details on using hashes here.

Provenance

The following attestation bundles were made for pennylane_metal-0.2.0-cp311-cp311-macosx_26_0_arm64.whl:

Publisher: wheels.yml on dereklei12/pennylane-metal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pennylane_metal-0.2.0-cp310-cp310-macosx_26_0_arm64.whl.

File metadata

File hashes

Hashes for pennylane_metal-0.2.0-cp310-cp310-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 ec5eb6871ce2d9eb5eecd53fd3cd8c56d3f5ca8a4b172392e850e329971ca45a
MD5 dff96b37418e02ff1b565e01ba3f98d8
BLAKE2b-256 bf32ef9bda40897dcd99318edb15560184b1b6f62d294a115df3cf6e0d523eac

See more details on using hashes here.

Provenance

The following attestation bundles were made for pennylane_metal-0.2.0-cp310-cp310-macosx_26_0_arm64.whl:

Publisher: wheels.yml on dereklei12/pennylane-metal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page