Transpilation
What transpile() does to a circuit on each kind of Qollab backend, how to see the result, and what the optimization-level warning on IonQ backends means.
Transpilation rewrites a circuit into the gates a backend can run. Where that rewrite happens depends on the backend you pick in the Select QPU dialog: in your browser for the local simulators and the IBM noise models, and on IonQ's side for IonQ simulators and hardware.
The warning on IonQ backends
When an IonQ backend is created, qiskit-ionq prints this in the runner console unless the transpile default is 0 or 1:
IonQTranspileLevelWarning: Transpiler default optimization_level=2. IonQ (QIS) recommends 0-1 to avoid aggressive re-synthesis; use transpile(..., optimization_level=1).
It is advice, not an error, and the run continues. It applies only if you call transpile() yourself: pass optimization_level=1 (or 0), and Qiskit keeps your circuit close to what you wrote before IonQ's compiler takes over. You do not need to call transpile() before submitting to an IonQ backend; the runner hands IonQ the circuit as written.
Seeing what a backend will run
transpile() takes your circuit and the pre-created backend and returns the rewritten circuit. count_ops() on the result is the quickest read of what changed.
from qiskit import QuantumCircuit, transpile
qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
qc.measure([0, 1], [0, 1])
compiled = transpile(qc, backend, optimization_level=1)
print(compiled.count_ops())
import { QuantumCircuit, transpile } from 'qiskit';
const circuit = QuantumCircuit(2, 2);
circuit.h(0);
circuit.cx(0, 1);
circuit.measure([0, 1], [0, 1]);
const compiled = transpile.callKwargs(circuit, backend, { optimization_level: 1 });
console.log(compiled.count_ops().toJs());
Transpiling submits no job and costs no credits.
Local simulators
The built-in simulator runs Qiskit's standard gates as written, but not composite instructions: a PauliEvolutionGate submitted untranspiled stops with unrecognized operation, and transpile() unrolls it first (a ZZ-type Hamiltonian becomes rzz and rz). Otherwise the built-in simulator runs the circuit you wrote.
IBM noise-model backends
The IBM backends in the dialog are local simulators carrying a real device's noise model. Like the built-in simulator, they reject an untranspiled PauliEvolutionGate (unknown instruction), so transpile first. Each device has a small native gate set, rz, sx, x and cz on the Heron and Nighthawk machines Qollab lists, and transpile() for one of them rewrites your circuit into those gates. The Bell pair above comes back as six rz, three sx and one cz: the H and the CX are gone, replaced by what the device physically runs. The rewritten circuit runs in your browser with that device's noise applied.
IonQ simulators and hardware
An IonQ backend accepts the whole standard gate set, so transpile() for one leaves the Bell pair as an H and a CX. The real rewrite happens after you submit, on IonQ's compiler, which turns your gates into IonQ's native gates and optimises the whole circuit; the gate count you see locally is not what runs, since the compiler both expands gates into native ones and cancels or merges what it can. See How your circuit is compiled and the Gate reference for what each gate becomes.
Because IonQ compiles again, qiskit-ionq asks you not to let Qiskit optimise aggressively first; that is the warning explained at the top of this page.
Related
Stay in the loop.
Get the latest tutorials, demos, and project showcases straight to your inbox. No noise, just the good stuff.
On this page
Running code