Personal blog of James Bryan Graves
Computer science (CS), quantum information science (QIS),
& software development & engineering (SDE)

PennyLane backend for Apple Silicon and Metal

https://github.com/datafatmunger/pennylane_metal

I like to use PennyLane to do some over my quantum information science (QIS) and quantum computer science (QCS) experiments. PennyLane is nice because it allows you swap backends between local CPU, Qiskit, Nvidia, etc…but there was no support, afaik, for Apple Silicon GPUs and Apple’s Metal, which one of my computers (an Apple MacBook Air, M2, 2022, 10 cores, Metal 3 support) has, so I’m introducing a plugin to add that support, works exactly like the other backends: https://github.com/datafatmunger/pennylane_metal

The plugin Seems to work. I tested normal stuff like basic gates, Bell/EPR states, Grover search, and Shor’s algorithms (in the example folder of the project). There is a small issue with the Python to Metal bridge framework (metalgpu), which I have a made patch for, just waiting to see if the metalgpu team wants merge the PR. Everything still works without the patch, issue stems from quantum computing’s “measurement problem” - most quantum algorithms require running multiple times (called “shots”) to gather statistical results. PennyLane, regardless of backend, handles this by instantiating multiple device instances during execution to perform these repeated measurements. However, the current metalgpu implementation uses a global singleton pattern in C++, which conflicts with PennyLane’s device instantiation approach. This causes segmentation faults when Python exits due to cleanup order issues between the multiple Python device instances and the single C++ singleton. Update: The fix for this issue has been merged into the main branch of the metalgpu repository.

tl;dr - for PennyLane users


dev = qml.device("metal.gpu", wires=2, shots=None)

Supported Quantum Gates

Single-Qubit Gates

Two-Qubit Gates

Installation

Prerequisites

Setup

  1. Clone the repository:

git clone <repository-url>
cd pennylane_metal
  1. Create a virtual environment and install dependencies:

python -m venv .venv
source .venv/bin/activate
pip install -e .
  1. Install PennyLane and other dependencies:

pip install pennylane numpy metalgpu

Usage

Basic Usage


import pennylane as qml

# Create device through PennyLane
dev = qml.device("metal.gpu", wires=2, shots=None)

@qml.qnode(dev)
def quantum_circuit():
    qml.Hadamard(wires=0)
    qml.CNOT(wires=[0, 1])
    return qml.state()

# Execute circuit
result = quantum_circuit()
print(f"Result: {result}")

Sampling with Shots


import pennylane as qml

# Device with shots for sampling
dev = qml.device("metal.gpu", wires=2, shots=1000)

@qml.qnode(dev)
def bell_state_sampling():
    qml.Hadamard(wires=0)
    qml.CNOT(wires=[0, 1])
    return qml.sample()

# Sample from Bell state
samples = bell_state_sampling()
print(f"Samples shape: {samples.shape}")
print(f"First 10 samples:\n{samples[:10]}")

Architecture

Metal Compute Shaders

The device uses custom Metal compute shaders (kernels.metal) to perform quantum operations:

Testing

Run the comprehensive test suite:


# Run all tests
python tests.py