mirror of
https://github.com/K-Dense-AI/claude-scientific-skills.git
synced 2026-03-27 07:09:27 +08:00
597 lines
13 KiB
Markdown
597 lines
13 KiB
Markdown
# Devices and Backends in PennyLane
|
|
|
|
## Table of Contents
|
|
1. [Built-in Simulators](#built-in-simulators)
|
|
2. [Hardware Plugins](#hardware-plugins)
|
|
3. [Device Selection](#device-selection)
|
|
4. [Device Configuration](#device-configuration)
|
|
5. [Custom Devices](#custom-devices)
|
|
6. [Performance Optimization](#performance-optimization)
|
|
|
|
## Built-in Simulators
|
|
|
|
### default.qubit
|
|
|
|
General-purpose state vector simulator:
|
|
|
|
```python
|
|
import pennylane as qml
|
|
|
|
# Basic initialization
|
|
dev = qml.device('default.qubit', wires=4)
|
|
|
|
# With shots (sampling mode)
|
|
dev = qml.device('default.qubit', wires=4, shots=1000)
|
|
|
|
# Specify wire labels
|
|
dev = qml.device('default.qubit', wires=['a', 'b', 'c', 'd'])
|
|
```
|
|
|
|
### default.mixed
|
|
|
|
Mixed-state simulator for noisy quantum systems:
|
|
|
|
```python
|
|
# Supports density matrix simulation
|
|
dev = qml.device('default.mixed', wires=2)
|
|
|
|
@qml.qnode(dev)
|
|
def noisy_circuit():
|
|
qml.Hadamard(wires=0)
|
|
|
|
# Apply noise
|
|
qml.DepolarizingChannel(0.1, wires=0)
|
|
|
|
qml.CNOT(wires=[0, 1])
|
|
|
|
# Amplitude damping
|
|
qml.AmplitudeDamping(0.05, wires=1)
|
|
|
|
return qml.expval(qml.PauliZ(0))
|
|
```
|
|
|
|
### default.qubit.torch, default.qubit.tf, default.qubit.jax
|
|
|
|
Framework-specific simulators with better integration:
|
|
|
|
```python
|
|
# PyTorch
|
|
dev = qml.device('default.qubit.torch', wires=4)
|
|
|
|
# TensorFlow
|
|
dev = qml.device('default.qubit.tf', wires=4)
|
|
|
|
# JAX
|
|
dev = qml.device('default.qubit.jax', wires=4)
|
|
```
|
|
|
|
### lightning.qubit
|
|
|
|
High-performance C++ simulator:
|
|
|
|
```python
|
|
# Faster than default.qubit
|
|
dev = qml.device('lightning.qubit', wires=20)
|
|
|
|
# Supports larger systems efficiently
|
|
@qml.qnode(dev)
|
|
def large_circuit():
|
|
for i in range(20):
|
|
qml.Hadamard(wires=i)
|
|
|
|
for i in range(19):
|
|
qml.CNOT(wires=[i, i+1])
|
|
|
|
return qml.expval(qml.PauliZ(0))
|
|
```
|
|
|
|
### default.clifford
|
|
|
|
Efficient simulator for Clifford circuits:
|
|
|
|
```python
|
|
# Only supports Clifford gates (H, S, CNOT, etc.)
|
|
dev = qml.device('default.clifford', wires=100)
|
|
|
|
@qml.qnode(dev)
|
|
def clifford_circuit():
|
|
qml.Hadamard(wires=0)
|
|
qml.CNOT(wires=[0, 1])
|
|
qml.S(wires=1)
|
|
# Cannot use RX, RY, RZ, etc.
|
|
|
|
return qml.expval(qml.PauliZ(0))
|
|
```
|
|
|
|
## Hardware Plugins
|
|
|
|
### IBM Quantum (Qiskit)
|
|
|
|
```bash
|
|
# Install plugin
|
|
uv pip install pennylane-qiskit
|
|
```
|
|
|
|
```python
|
|
import pennylane as qml
|
|
|
|
# Use IBM simulator
|
|
dev = qml.device('qiskit.aer', wires=2)
|
|
|
|
# Use IBM quantum hardware
|
|
dev = qml.device(
|
|
'qiskit.ibmq',
|
|
wires=2,
|
|
backend='ibmq_manila', # Specify backend
|
|
shots=1024
|
|
)
|
|
|
|
# With API token
|
|
dev = qml.device(
|
|
'qiskit.ibmq',
|
|
wires=2,
|
|
backend='ibmq_manila',
|
|
ibmqx_token='YOUR_API_TOKEN'
|
|
)
|
|
|
|
@qml.qnode(dev)
|
|
def circuit():
|
|
qml.Hadamard(wires=0)
|
|
qml.CNOT(wires=[0, 1])
|
|
return qml.expval(qml.PauliZ(0))
|
|
```
|
|
|
|
### Amazon Braket
|
|
|
|
```bash
|
|
# Install plugin
|
|
uv pip install amazon-braket-pennylane-plugin
|
|
```
|
|
|
|
```python
|
|
# Use Braket simulators
|
|
dev = qml.device(
|
|
'braket.local.qubit',
|
|
wires=2
|
|
)
|
|
|
|
# Use AWS simulators
|
|
dev = qml.device(
|
|
'braket.aws.qubit',
|
|
device_arn='arn:aws:braket:::device/quantum-simulator/amazon/sv1',
|
|
wires=4,
|
|
s3_destination_folder=('amazon-braket-outputs', 'outputs')
|
|
)
|
|
|
|
# Use quantum hardware (IonQ, Rigetti, etc.)
|
|
dev = qml.device(
|
|
'braket.aws.qubit',
|
|
device_arn='arn:aws:braket:us-east-1::device/qpu/ionq/Harmony',
|
|
wires=11,
|
|
shots=1000,
|
|
s3_destination_folder=('amazon-braket-outputs', 'outputs')
|
|
)
|
|
```
|
|
|
|
### Google Cirq
|
|
|
|
```bash
|
|
# Install plugin
|
|
uv pip install pennylane-cirq
|
|
```
|
|
|
|
```python
|
|
# Use Cirq simulator
|
|
dev = qml.device('cirq.simulator', wires=2)
|
|
|
|
# Use Cirq with qsim (faster)
|
|
dev = qml.device('cirq.qsim', wires=20)
|
|
|
|
# Use Google quantum hardware (if you have access)
|
|
dev = qml.device(
|
|
'cirq.pasqal',
|
|
wires=2,
|
|
device='rainbow',
|
|
shots=1000
|
|
)
|
|
```
|
|
|
|
### Rigetti Forest
|
|
|
|
```bash
|
|
# Install plugin
|
|
uv pip install pennylane-rigetti
|
|
```
|
|
|
|
```python
|
|
# Use QVM (Quantum Virtual Machine)
|
|
dev = qml.device('rigetti.qvm', device='4q-qvm', shots=1000)
|
|
|
|
# Use Rigetti QPU
|
|
dev = qml.device('rigetti.qpu', device='Aspen-M-3', shots=1000)
|
|
```
|
|
|
|
### Microsoft Azure Quantum
|
|
|
|
```bash
|
|
# Install plugin
|
|
uv pip install pennylane-azure
|
|
```
|
|
|
|
```python
|
|
# Use Azure simulators
|
|
dev = qml.device(
|
|
'azure.simulator',
|
|
wires=4,
|
|
workspace='your-workspace',
|
|
resource_group='your-resource-group',
|
|
subscription_id='your-subscription-id'
|
|
)
|
|
|
|
# Use IonQ on Azure
|
|
dev = qml.device(
|
|
'azure.ionq',
|
|
wires=11,
|
|
workspace='your-workspace',
|
|
resource_group='your-resource-group',
|
|
subscription_id='your-subscription-id',
|
|
shots=500
|
|
)
|
|
```
|
|
|
|
### IonQ
|
|
|
|
```bash
|
|
# Install plugin
|
|
uv pip install pennylane-ionq
|
|
```
|
|
|
|
```python
|
|
# Use IonQ hardware
|
|
dev = qml.device(
|
|
'ionq.simulator', # or 'ionq.qpu'
|
|
wires=11,
|
|
shots=1024,
|
|
api_key='your_api_key'
|
|
)
|
|
```
|
|
|
|
### Xanadu Hardware (Borealis)
|
|
|
|
```python
|
|
# Photonic quantum computer
|
|
dev = qml.device(
|
|
'strawberryfields.remote',
|
|
backend='borealis',
|
|
shots=10000
|
|
)
|
|
```
|
|
|
|
## Device Selection
|
|
|
|
### Choosing the Right Device
|
|
|
|
```python
|
|
def select_device(n_qubits, use_hardware=False, noise_model=None):
|
|
"""Select appropriate device based on requirements."""
|
|
|
|
if use_hardware:
|
|
# Use real quantum hardware
|
|
if n_qubits <= 11:
|
|
return qml.device('ionq.qpu', wires=n_qubits, shots=1000)
|
|
elif n_qubits <= 127:
|
|
return qml.device('qiskit.ibmq', wires=n_qubits, shots=1024)
|
|
else:
|
|
raise ValueError(f"No hardware available for {n_qubits} qubits")
|
|
|
|
elif noise_model:
|
|
# Use noisy simulator
|
|
return qml.device('default.mixed', wires=n_qubits)
|
|
|
|
else:
|
|
# Use ideal simulator
|
|
if n_qubits <= 20:
|
|
return qml.device('lightning.qubit', wires=n_qubits)
|
|
else:
|
|
return qml.device('default.qubit', wires=n_qubits)
|
|
|
|
# Usage
|
|
dev = select_device(n_qubits=10, use_hardware=False)
|
|
```
|
|
|
|
### Device Capabilities
|
|
|
|
```python
|
|
# Check device capabilities
|
|
dev = qml.device('default.qubit', wires=4)
|
|
|
|
print("Device name:", dev.name)
|
|
print("Number of wires:", dev.num_wires)
|
|
print("Supports shots:", dev.shots is not None)
|
|
|
|
# Check supported operations
|
|
print("Supported gates:", dev.operations)
|
|
|
|
# Check supported observables
|
|
print("Supported observables:", dev.observables)
|
|
```
|
|
|
|
## Device Configuration
|
|
|
|
### Setting Shots
|
|
|
|
```python
|
|
# Exact simulation (no shots)
|
|
dev = qml.device('default.qubit', wires=2)
|
|
|
|
@qml.qnode(dev)
|
|
def exact_circuit():
|
|
qml.Hadamard(wires=0)
|
|
return qml.expval(qml.PauliZ(0))
|
|
|
|
result = exact_circuit() # Returns exact expectation
|
|
|
|
# Sampling mode (with shots)
|
|
dev_sampled = qml.device('default.qubit', wires=2, shots=1000)
|
|
|
|
@qml.qnode(dev_sampled)
|
|
def sampled_circuit():
|
|
qml.Hadamard(wires=0)
|
|
return qml.expval(qml.PauliZ(0))
|
|
|
|
result = sampled_circuit() # Estimated from samples
|
|
```
|
|
|
|
### Dynamic Shots
|
|
|
|
```python
|
|
# Change shots per execution
|
|
dev = qml.device('default.qubit', wires=2)
|
|
|
|
@qml.qnode(dev)
|
|
def circuit():
|
|
qml.Hadamard(wires=0)
|
|
return qml.expval(qml.PauliZ(0))
|
|
|
|
# Different shot numbers
|
|
result_100 = circuit(shots=100)
|
|
result_1000 = circuit(shots=1000)
|
|
result_exact = circuit(shots=None) # Exact
|
|
```
|
|
|
|
### Analytic Mode vs Finite Shots
|
|
|
|
```python
|
|
# Compare analytic vs sampled
|
|
dev_analytic = qml.device('default.qubit', wires=2)
|
|
dev_sampled = qml.device('default.qubit', wires=2, shots=1000)
|
|
|
|
@qml.qnode(dev_analytic)
|
|
def circuit_analytic(x):
|
|
qml.RX(x, wires=0)
|
|
return qml.expval(qml.PauliZ(0))
|
|
|
|
@qml.qnode(dev_sampled)
|
|
def circuit_sampled(x):
|
|
qml.RX(x, wires=0)
|
|
return qml.expval(qml.PauliZ(0))
|
|
|
|
import numpy as np
|
|
x = np.pi / 4
|
|
|
|
print(f"Analytic: {circuit_analytic(x)}")
|
|
print(f"Sampled: {circuit_sampled(x)}")
|
|
print(f"Exact value: {np.cos(x)}")
|
|
```
|
|
|
|
### Seed for Reproducibility
|
|
|
|
```python
|
|
# Set random seed
|
|
dev = qml.device('default.qubit', wires=2, shots=1000, seed=42)
|
|
|
|
@qml.qnode(dev)
|
|
def circuit():
|
|
qml.Hadamard(wires=0)
|
|
return qml.sample(qml.PauliZ(0))
|
|
|
|
# Reproducible results
|
|
samples1 = circuit()
|
|
samples2 = circuit() # Same as samples1 if seed is set
|
|
```
|
|
|
|
## Custom Devices
|
|
|
|
### Creating a Custom Device
|
|
|
|
```python
|
|
from pennylane.devices import DefaultQubit
|
|
|
|
class CustomDevice(DefaultQubit):
|
|
"""Custom quantum device with additional features."""
|
|
|
|
name = 'Custom device'
|
|
short_name = 'custom'
|
|
pennylane_requires = '>=0.30.0'
|
|
version = '0.1.0'
|
|
author = 'Your Name'
|
|
|
|
def __init__(self, wires, shots=None, **kwargs):
|
|
super().__init__(wires=wires, shots=shots)
|
|
# Custom initialization
|
|
|
|
def apply(self, operations, **kwargs):
|
|
"""Apply operations with custom logic."""
|
|
# Custom operation handling
|
|
for op in operations:
|
|
# Log or modify operations
|
|
print(f"Applying: {op.name}")
|
|
|
|
# Call parent implementation
|
|
super().apply(operations, **kwargs)
|
|
|
|
# Use custom device
|
|
dev = CustomDevice(wires=4)
|
|
```
|
|
|
|
### Plugin Development
|
|
|
|
```python
|
|
# Define custom plugin operations
|
|
class CustomGate(qml.operation.Operation):
|
|
"""Custom quantum gate."""
|
|
|
|
num_wires = 1
|
|
num_params = 1
|
|
par_domain = 'R'
|
|
|
|
def decomposition(self):
|
|
"""Decompose into standard gates."""
|
|
theta = self.parameters[0]
|
|
wires = self.wires
|
|
|
|
return [
|
|
qml.RY(theta / 2, wires=wires),
|
|
qml.RZ(theta, wires=wires),
|
|
qml.RY(-theta / 2, wires=wires)
|
|
]
|
|
|
|
# Register with device
|
|
qml.ops.CustomGate = CustomGate
|
|
```
|
|
|
|
## Performance Optimization
|
|
|
|
### Batch Execution
|
|
|
|
```python
|
|
# Execute multiple parameter sets efficiently
|
|
dev = qml.device('default.qubit', wires=2)
|
|
|
|
@qml.qnode(dev)
|
|
def circuit(params):
|
|
qml.RX(params[0], wires=0)
|
|
qml.RY(params[1], wires=1)
|
|
qml.CNOT(wires=[0, 1])
|
|
return qml.expval(qml.PauliZ(0))
|
|
|
|
# Batch parameters
|
|
params_batch = np.random.random((100, 2))
|
|
|
|
# Vectorized execution (faster)
|
|
results = [circuit(p) for p in params_batch]
|
|
```
|
|
|
|
### Device Caching
|
|
|
|
```python
|
|
# Cache device for reuse
|
|
_device_cache = {}
|
|
|
|
def get_device(n_qubits, device_type='default.qubit'):
|
|
"""Get or create cached device."""
|
|
key = (device_type, n_qubits)
|
|
|
|
if key not in _device_cache:
|
|
_device_cache[key] = qml.device(device_type, wires=n_qubits)
|
|
|
|
return _device_cache[key]
|
|
|
|
# Reuse devices
|
|
dev1 = get_device(4)
|
|
dev2 = get_device(4) # Returns same device
|
|
```
|
|
|
|
### JIT Compilation with Catalyst
|
|
|
|
```python
|
|
# Install Catalyst
|
|
# uv pip install pennylane-catalyst
|
|
|
|
import pennylane as qml
|
|
from catalyst import qjit
|
|
|
|
dev = qml.device('lightning.qubit', wires=4)
|
|
|
|
@qjit # Just-in-time compilation
|
|
@qml.qnode(dev)
|
|
def compiled_circuit(x):
|
|
qml.RX(x, wires=0)
|
|
qml.Hadamard(wires=1)
|
|
qml.CNOT(wires=[0, 1])
|
|
return qml.expval(qml.PauliZ(0))
|
|
|
|
# First call compiles, subsequent calls are fast
|
|
result = compiled_circuit(0.5)
|
|
```
|
|
|
|
### Parallel Execution
|
|
|
|
```python
|
|
from multiprocessing import Pool
|
|
|
|
def run_circuit(params):
|
|
"""Run circuit with given parameters."""
|
|
dev = qml.device('default.qubit', wires=4)
|
|
|
|
@qml.qnode(dev)
|
|
def circuit(p):
|
|
# Circuit definition
|
|
return qml.expval(qml.PauliZ(0))
|
|
|
|
return circuit(params)
|
|
|
|
# Parallel execution
|
|
param_list = [np.random.random(10) for _ in range(100)]
|
|
|
|
with Pool(processes=4) as pool:
|
|
results = pool.map(run_circuit, param_list)
|
|
```
|
|
|
|
### GPU Acceleration
|
|
|
|
```python
|
|
# Use GPU-accelerated devices if available
|
|
try:
|
|
dev = qml.device('lightning.gpu', wires=20)
|
|
except:
|
|
dev = qml.device('lightning.qubit', wires=20)
|
|
|
|
@qml.qnode(dev)
|
|
def gpu_circuit():
|
|
# Large circuit benefits from GPU
|
|
for i in range(20):
|
|
qml.Hadamard(wires=i)
|
|
|
|
for i in range(19):
|
|
qml.CNOT(wires=[i, i+1])
|
|
|
|
return [qml.expval(qml.PauliZ(i)) for i in range(20)]
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
1. **Start with simulators** - Test on `default.qubit` before hardware
|
|
2. **Use lightning for speed** - Switch to `lightning.qubit` for larger circuits
|
|
3. **Match device to task** - Use `default.mixed` for noise studies
|
|
4. **Cache devices** - Reuse device objects to avoid initialization overhead
|
|
5. **Set appropriate shots** - Balance accuracy vs speed
|
|
6. **Check capabilities** - Verify device supports required operations
|
|
7. **Handle hardware errors** - Implement retries and error mitigation
|
|
8. **Monitor costs** - Track hardware usage and costs
|
|
9. **Use JIT when possible** - Compile circuits with Catalyst for speedup
|
|
10. **Test locally first** - Validate on simulators before submitting to hardware
|
|
|
|
## Device Comparison
|
|
|
|
| Device | Type | Max Qubits | Speed | Noise | Use Case |
|
|
|--------|------|-----------|-------|-------|----------|
|
|
| default.qubit | Simulator | ~25 | Medium | No | General purpose |
|
|
| lightning.qubit | Simulator | ~30 | Fast | No | Large circuits |
|
|
| default.mixed | Simulator | ~15 | Slow | Yes | Noise studies |
|
|
| default.clifford | Simulator | 100+ | Very fast | No | Clifford circuits |
|
|
| IBM Quantum | Hardware | 127 | Slow | Yes | Real experiments |
|
|
| IonQ | Hardware | 11 | Slow | Low | High fidelity |
|
|
| Rigetti | Hardware | 80 | Slow | Yes | Research |
|
|
| Borealis | Hardware | 216 | Slow | Yes | Photonic QC |
|