mirror of
https://github.com/K-Dense-AI/claude-scientific-skills.git
synced 2026-01-26 16:58:56 +08:00
434 lines
9.3 KiB
Markdown
434 lines
9.3 KiB
Markdown
# Hardware Backends and Execution
|
|
|
|
Qiskit is backend-agnostic and supports execution on simulators and real quantum hardware from multiple providers.
|
|
|
|
## Backend Types
|
|
|
|
### Local Simulators
|
|
- Run on your machine
|
|
- No account required
|
|
- Perfect for development and testing
|
|
|
|
### Cloud-Based Hardware
|
|
- IBM Quantum (100+ qubit systems)
|
|
- IonQ (trapped ion)
|
|
- Amazon Braket (Rigetti, IonQ, Oxford Quantum Circuits)
|
|
- Other providers via plugins
|
|
|
|
## IBM Quantum Backends
|
|
|
|
### Connecting to IBM Quantum
|
|
|
|
```python
|
|
from qiskit_ibm_runtime import QiskitRuntimeService
|
|
|
|
# First time: save credentials
|
|
QiskitRuntimeService.save_account(
|
|
channel="ibm_quantum",
|
|
token="YOUR_IBM_QUANTUM_TOKEN"
|
|
)
|
|
|
|
# Subsequent sessions: load credentials
|
|
service = QiskitRuntimeService()
|
|
```
|
|
|
|
### Listing Available Backends
|
|
|
|
```python
|
|
# List all available backends
|
|
backends = service.backends()
|
|
for backend in backends:
|
|
print(f"{backend.name}: {backend.num_qubits} qubits")
|
|
|
|
# Filter by minimum qubits
|
|
backends_127q = service.backends(min_num_qubits=127)
|
|
|
|
# Get specific backend
|
|
backend = service.backend("ibm_brisbane")
|
|
backend = service.least_busy() # Get least busy backend
|
|
```
|
|
|
|
### Backend Properties
|
|
|
|
```python
|
|
backend = service.backend("ibm_brisbane")
|
|
|
|
# Basic info
|
|
print(f"Name: {backend.name}")
|
|
print(f"Qubits: {backend.num_qubits}")
|
|
print(f"Version: {backend.version}")
|
|
print(f"Status: {backend.status()}")
|
|
|
|
# Coupling map (qubit connectivity)
|
|
print(backend.coupling_map)
|
|
|
|
# Basis gates
|
|
print(backend.configuration().basis_gates)
|
|
|
|
# Qubit properties
|
|
print(backend.qubit_properties(0)) # Properties of qubit 0
|
|
```
|
|
|
|
### Checking Backend Status
|
|
|
|
```python
|
|
status = backend.status()
|
|
print(f"Operational: {status.operational}")
|
|
print(f"Pending jobs: {status.pending_jobs}")
|
|
print(f"Status message: {status.status_msg}")
|
|
```
|
|
|
|
## Running on IBM Quantum Hardware
|
|
|
|
### Using Runtime Primitives
|
|
|
|
```python
|
|
from qiskit import QuantumCircuit, transpile
|
|
from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler
|
|
|
|
service = QiskitRuntimeService()
|
|
backend = service.backend("ibm_brisbane")
|
|
|
|
# Create and transpile circuit
|
|
qc = QuantumCircuit(2)
|
|
qc.h(0)
|
|
qc.cx(0, 1)
|
|
qc.measure_all()
|
|
|
|
# Transpile for backend
|
|
transpiled_qc = transpile(qc, backend=backend, optimization_level=3)
|
|
|
|
# Run with Sampler
|
|
sampler = Sampler(backend)
|
|
job = sampler.run([transpiled_qc], shots=1024)
|
|
|
|
# Retrieve results
|
|
result = job.result()
|
|
counts = result[0].data.meas.get_counts()
|
|
print(counts)
|
|
```
|
|
|
|
### Job Management
|
|
|
|
```python
|
|
# Submit job
|
|
job = sampler.run([qc], shots=1024)
|
|
|
|
# Get job ID (save for later retrieval)
|
|
job_id = job.job_id()
|
|
print(f"Job ID: {job_id}")
|
|
|
|
# Check job status
|
|
print(job.status())
|
|
|
|
# Wait for completion
|
|
result = job.result()
|
|
|
|
# Retrieve job later
|
|
service = QiskitRuntimeService()
|
|
retrieved_job = service.job(job_id)
|
|
result = retrieved_job.result()
|
|
```
|
|
|
|
### Job Queuing
|
|
|
|
```python
|
|
# Check queue position
|
|
job_status = job.status()
|
|
print(f"Queue position: {job.queue_position()}")
|
|
|
|
# Cancel job if needed
|
|
job.cancel()
|
|
```
|
|
|
|
## Session Mode
|
|
|
|
Use sessions for iterative algorithms (VQE, QAOA) to reduce queue time:
|
|
|
|
```python
|
|
from qiskit_ibm_runtime import Session, SamplerV2 as Sampler
|
|
|
|
service = QiskitRuntimeService()
|
|
backend = service.backend("ibm_brisbane")
|
|
|
|
with Session(backend=backend) as session:
|
|
sampler = Sampler(session=session)
|
|
|
|
# Multiple iterations in same session
|
|
for iteration in range(10):
|
|
# Parameterized circuit
|
|
qc = create_parameterized_circuit(params[iteration])
|
|
job = sampler.run([qc], shots=1024)
|
|
result = job.result()
|
|
|
|
# Update parameters based on results
|
|
params[iteration + 1] = optimize(result)
|
|
```
|
|
|
|
Session benefits:
|
|
- Reduced queue waiting between iterations
|
|
- Guaranteed backend availability during session
|
|
- Better for variational algorithms
|
|
|
|
## Batch Mode
|
|
|
|
Use batch mode for independent parallel jobs:
|
|
|
|
```python
|
|
from qiskit_ibm_runtime import Batch, SamplerV2 as Sampler
|
|
|
|
service = QiskitRuntimeService()
|
|
backend = service.backend("ibm_brisbane")
|
|
|
|
with Batch(backend=backend) as batch:
|
|
sampler = Sampler(session=batch)
|
|
|
|
# Submit multiple independent jobs
|
|
jobs = []
|
|
for qc in circuit_list:
|
|
job = sampler.run([qc], shots=1024)
|
|
jobs.append(job)
|
|
|
|
# Collect all results
|
|
results = [job.result() for job in jobs]
|
|
```
|
|
|
|
## Local Simulators
|
|
|
|
### StatevectorSampler (Ideal Simulation)
|
|
|
|
```python
|
|
from qiskit.primitives import StatevectorSampler
|
|
|
|
sampler = StatevectorSampler()
|
|
result = sampler.run([qc], shots=1024).result()
|
|
counts = result[0].data.meas.get_counts()
|
|
```
|
|
|
|
### Aer Simulator (Realistic Noise)
|
|
|
|
```python
|
|
from qiskit_aer import AerSimulator
|
|
from qiskit_ibm_runtime import SamplerV2 as Sampler
|
|
|
|
# Ideal simulation
|
|
simulator = AerSimulator()
|
|
|
|
# Simulate with backend noise model
|
|
backend = service.backend("ibm_brisbane")
|
|
noisy_simulator = AerSimulator.from_backend(backend)
|
|
|
|
# Run simulation
|
|
transpiled_qc = transpile(qc, simulator)
|
|
sampler = Sampler(simulator)
|
|
job = sampler.run([transpiled_qc], shots=1024)
|
|
result = job.result()
|
|
```
|
|
|
|
### Aer GPU Acceleration
|
|
|
|
```python
|
|
# Use GPU for faster simulation
|
|
simulator = AerSimulator(method='statevector', device='GPU')
|
|
```
|
|
|
|
## Third-Party Providers
|
|
|
|
### IonQ
|
|
|
|
IonQ offers trapped-ion quantum computers with all-to-all connectivity:
|
|
|
|
```python
|
|
from qiskit_ionq import IonQProvider
|
|
|
|
provider = IonQProvider("YOUR_IONQ_API_TOKEN")
|
|
|
|
# List IonQ backends
|
|
backends = provider.backends()
|
|
backend = provider.get_backend("ionq_qpu")
|
|
|
|
# Run circuit
|
|
job = backend.run(qc, shots=1024)
|
|
result = job.result()
|
|
```
|
|
|
|
### Amazon Braket
|
|
|
|
```python
|
|
from qiskit_braket_provider import BraketProvider
|
|
|
|
provider = BraketProvider()
|
|
|
|
# List available devices
|
|
backends = provider.backends()
|
|
|
|
# Use specific device
|
|
backend = provider.get_backend("Rigetti")
|
|
job = backend.run(qc, shots=1024)
|
|
result = job.result()
|
|
```
|
|
|
|
## Error Mitigation
|
|
|
|
### Measurement Error Mitigation
|
|
|
|
```python
|
|
from qiskit_ibm_runtime import SamplerV2 as Sampler, Options
|
|
|
|
# Configure error mitigation
|
|
options = Options()
|
|
options.resilience_level = 1 # 0=none, 1=minimal, 2=moderate, 3=heavy
|
|
|
|
sampler = Sampler(backend, options=options)
|
|
job = sampler.run([qc], shots=1024)
|
|
result = job.result()
|
|
```
|
|
|
|
### Error Mitigation Levels
|
|
|
|
- **Level 0**: No mitigation
|
|
- **Level 1**: Readout error mitigation
|
|
- **Level 2**: Level 1 + gate error mitigation
|
|
- **Level 3**: Level 2 + advanced techniques
|
|
|
|
**Qiskit's Samplomatic package** can reduce sampling overhead by up to 100x with probabilistic error cancellation.
|
|
|
|
### Zero Noise Extrapolation (ZNE)
|
|
|
|
```python
|
|
options = Options()
|
|
options.resilience_level = 2
|
|
options.resilience.zne_mitigation = True
|
|
|
|
sampler = Sampler(backend, options=options)
|
|
```
|
|
|
|
## Monitoring Usage and Costs
|
|
|
|
### Check Account Usage
|
|
|
|
```python
|
|
# For IBM Quantum
|
|
service = QiskitRuntimeService()
|
|
|
|
# Check remaining credits
|
|
print(service.usage())
|
|
```
|
|
|
|
### Estimate Job Cost
|
|
|
|
```python
|
|
from qiskit_ibm_runtime import EstimatorV2 as Estimator
|
|
|
|
backend = service.backend("ibm_brisbane")
|
|
|
|
# Estimate job cost
|
|
estimator = Estimator(backend)
|
|
# Cost depends on circuit complexity and shots
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
### 1. Always Transpile Before Running
|
|
|
|
```python
|
|
# Bad: Run without transpilation
|
|
job = sampler.run([qc], shots=1024)
|
|
|
|
# Good: Transpile first
|
|
qc_transpiled = transpile(qc, backend=backend, optimization_level=3)
|
|
job = sampler.run([qc_transpiled], shots=1024)
|
|
```
|
|
|
|
### 2. Test with Simulators First
|
|
|
|
```python
|
|
# Test with noisy simulator before hardware
|
|
noisy_sim = AerSimulator.from_backend(backend)
|
|
qc_test = transpile(qc, noisy_sim, optimization_level=3)
|
|
|
|
# Verify results look reasonable
|
|
# Then run on hardware
|
|
```
|
|
|
|
### 3. Use Appropriate Shot Counts
|
|
|
|
```python
|
|
# For optimization algorithms: fewer shots (100-1000)
|
|
# For final measurements: more shots (10000+)
|
|
|
|
# Adaptive shots based on stage
|
|
shots_optimization = 500
|
|
shots_final = 10000
|
|
```
|
|
|
|
### 4. Choose Backend Strategically
|
|
|
|
```python
|
|
# For testing: Use least busy backend
|
|
backend = service.least_busy(min_num_qubits=5)
|
|
|
|
# For production: Use backend matching requirements
|
|
backend = service.backend("ibm_brisbane") # 127 qubits
|
|
```
|
|
|
|
### 5. Use Sessions for Variational Algorithms
|
|
|
|
Sessions are ideal for VQE, QAOA, and other iterative algorithms.
|
|
|
|
### 6. Monitor Job Status
|
|
|
|
```python
|
|
import time
|
|
|
|
job = sampler.run([qc], shots=1024)
|
|
|
|
while job.status().name not in ['DONE', 'ERROR', 'CANCELLED']:
|
|
print(f"Status: {job.status().name}")
|
|
time.sleep(10)
|
|
|
|
result = job.result()
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Issue: "Backend not found"
|
|
```python
|
|
# List available backends
|
|
print([b.name for b in service.backends()])
|
|
```
|
|
|
|
### Issue: "Invalid credentials"
|
|
```python
|
|
# Re-save credentials
|
|
QiskitRuntimeService.save_account(
|
|
channel="ibm_quantum",
|
|
token="YOUR_TOKEN",
|
|
overwrite=True
|
|
)
|
|
```
|
|
|
|
### Issue: Long queue times
|
|
```python
|
|
# Use least busy backend
|
|
backend = service.least_busy(min_num_qubits=5)
|
|
|
|
# Or use batch mode for multiple independent jobs
|
|
```
|
|
|
|
### Issue: Job fails with "Circuit too large"
|
|
```python
|
|
# Reduce circuit complexity
|
|
# Use higher transpilation optimization
|
|
qc_opt = transpile(qc, backend=backend, optimization_level=3)
|
|
```
|
|
|
|
## Backend Comparison
|
|
|
|
| Provider | Connectivity | Gate Set | Notes |
|
|
|----------|-------------|----------|--------|
|
|
| IBM Quantum | Limited | CX, RZ, SX, X | 100+ qubit systems, high quality |
|
|
| IonQ | All-to-all | GPI, GPI2, MS | Trapped ion, low error rates |
|
|
| Rigetti | Limited | CZ, RZ, RX | Superconducting qubits |
|
|
| Oxford Quantum Circuits | Limited | ECR, RZ, SX | Coaxmon technology |
|