-
Notifications
You must be signed in to change notification settings - Fork 28
Open
Description
What feature would you like to see added? Why is it valuable?
having a local noisy aer simulator that uses the characterization data to be accurate enough for testing
What is the expected behavior, in detail?
instead of using any local simulator, use an ionqsimulator("qpu.forte-1") or smth!
Can you help make this feature a reality? By yourself? If not, what support would you need?
from qiskit.circuit import QuantumCircuit
from qiskit.circuit.library import UnitaryGate
from qiskit.quantum_info import Operator
from qiskit_aer import AerSimulator
from qiskit_aer.noise import (
NoiseModel,
depolarizing_error,
thermal_relaxation_error,
ReadoutError,
)
from qiskit_ionq import IonQProvider
IONQ_LABELS = {"gpi", "gpi2", "ms", "zz"}
BACKEND_ID = "qpu.aria-1"
# 1. Fetch the latest characterization
def latest_characterization() -> dict:
provider = IonQProvider() # uses $IONQ_API_KEY
backend = provider.get_backend(BACKEND_ID, gateset="native")
char = backend.client.get_calibration_data(BACKEND_ID)[0]
return char
# 2. Build a Qiskit‑Aer NoiseModel from the characterization data
def noise_model_from_char(char: dict) -> NoiseModel:
t1, t2 = char["timing"]["t1"], char["timing"]["t2"]
t1q, t2q = char["timing"]["1q"], char["timing"]["2q"]
p1 = 1 - char["fidelity"]["1q"]["median"]
p2 = 1 - char["fidelity"]["2q"]["median"]
ps = 1 - char["fidelity"]["spam"]["median"]
# elementary errors
err1q = depolarizing_error(p1, 1).compose(thermal_relaxation_error(t1, t2, t1q))
base_tr = thermal_relaxation_error(t1, t2, t2q)
err2q = depolarizing_error(p2, 2).compose(base_tr.tensor(base_tr))
err_ro = ReadoutError([[1 - ps, ps], [ps, 1 - ps]])
noise = NoiseModel()
noise.add_basis_gates(["unitary"]) # tell Aer we will send custom unitaries
noise.add_all_qubit_quantum_error(err1q, ["gpi", "gpi2", "rz"])
for q0, q1 in map(tuple, char["connectivity"]):
noise.add_quantum_error(err2q, ["ms"], [q0, q1])
noise.add_all_qubit_readout_error(err_ro)
return noise
# 3. Convert IonQ native gates into Aer‑legal UnitaryGate ops
def ionq_to_unitary(circ: QuantumCircuit) -> QuantumCircuit:
"""Return a copy where every IonQ native gate is a UnitaryGate."""
out = QuantumCircuit(*circ.qregs, *circ.cregs, name=circ.name)
for inst, qargs, cargs in circ.data:
if inst.name in IONQ_LABELS:
mat = Operator(inst).data
inst = UnitaryGate(mat, label=inst.name)
out.append(inst, qargs, cargs)
return out
# 4. Get a simulator with noise model and characterization
def get_simulator() -> tuple[AerSimulator, dict]:
char = latest_characterization()
noise = noise_model_from_char(char)
sim = AerSimulator(noise_model=noise)
return sim, char
# 5. Example usage
from qiskit import QuantumCircuit, transpile
from qiskit.visualization import plot_histogram
sim, char = get_simulator()
backend = IonQProvider().get_backend(BACKEND_ID, gateset="native")
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
qc.measure_all()
t_native = transpile(qc, backend, optimization_level=3)
t_aer = ionq_to_unitary(t_native)
result = sim.run(t_aer, shots=1024).result()
counts = result.get_counts()
print("IonQ-Aria-1 noisy counts:", counts)
plot_histogram(counts)
bachase
Metadata
Metadata
Assignees
Labels
No labels