mirror of
https://github.com/K-Dense-AI/claude-scientific-skills.git
synced 2026-01-26 16:58:56 +08:00
9.3 KiB
9.3 KiB
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
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
# 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
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
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
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
# 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
# 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:
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:
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)
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)
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
# 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:
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
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
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)
options = Options()
options.resilience_level = 2
options.resilience.zne_mitigation = True
sampler = Sampler(backend, options=options)
Monitoring Usage and Costs
Check Account Usage
# For IBM Quantum
service = QiskitRuntimeService()
# Check remaining credits
print(service.usage())
Estimate Job Cost
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
# 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
# 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
# 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
# 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
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"
# List available backends
print([b.name for b in service.backends()])
Issue: "Invalid credentials"
# Re-save credentials
QiskitRuntimeService.save_account(
channel="ibm_quantum",
token="YOUR_TOKEN",
overwrite=True
)
Issue: Long queue times
# 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"
# 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 |