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
- Pauli Gates:
PauliX
,PauliY
,PauliZ
- Hadamard Gate:
Hadamard
- Rotation Gates:
RX
,RY
,RZ
- Phase Gates:
PhaseShift
Two-Qubit Gates
- CNOT: Controlled-X gate
- CZ: Controlled-Z gate
- SWAP: Qubit swap gate
Installation
Prerequisites
- macOS with Metal-compatible GPU
- Python 3.8+
- PennyLane
- NumPy
- metalgpu (Metal GPU interface library)
Setup
- Clone the repository:
git clone <repository-url>
cd pennylane_metal
- Create a virtual environment and install dependencies:
python -m venv .venv
source .venv/bin/activate
pip install -e .
- 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:
- Single-qubit gates: Optimized parallel computation across quantum state amplitudes
- Two-qubit gates: Efficient controlled operations with proper qubit indexing
- State sampling: GPU-based random sampling from quantum probability distributions
Testing
Run the comprehensive test suite:
# Run all tests
python tests.py