Quantum circuit transpilation¶
AQT backends only natively implement a limited but complete set of quantum gates. The Qiskit transpiler allows transforming any non-conditional quantum circuit to use only supported quantum gates. The set of supported gates is defined in the transpiler Target used by the AQT backends:
print(list(backend.target.operation_names))
['rz', 'r', 'rxx', 'measure']
The transpiler’s entry point is the qiskit.transpile function. The optimization level can be tuned using the optimization_level=0,1,2,3 argument. One can inspect how the circuit is converted from the original one:
to the transpiled one:
Tip
While all optimization levels produce circuits compatible with the AQT API, optimization level 3 typically produces circuits with the least number of gates, thus decreasing the circuit evaluation duration and mitigating errors.
Transpiler bypass¶
Warning
We highly recommend to always use the built-in transpiler, at least with optimization_level=0. This guarantees that the quantum circuit is valid for submission to the AQT cloud. In particular, it wraps the gate parameters to fit in the restricted ranges accepted by the AQT API. In addition, higher optimization levels may significantly improve the circuit execution speed.
If a circuit is already defined in terms of the native gates set with their restricted parameter ranges and no optimization is wanted, it can be submitted for execution without any additional transformation using the run method:
native_circuit = qiskit.QuantumCircuit(2)
native_circuit.rxx(pi/2, 0, 1)
native_circuit.r(pi, 0, 0)
native_circuit.r(pi, pi, 1)
native_circuit.measure_all()
job = backend.run(native_circuit)
result = job.result()
if result.success:
print(result.get_counts())
else:
raise RuntimeError
{'00': 48, '11': 52}
Circuits that do not satisfy the AQT API restrictions are rejected by raising a ValueError exception.
Transpiler plugin¶
The built-in transpiler largely leverages the qiskit.transpiler. Custom passes are registered in addition to the presets, irrespective of the optimization level, to ensure that the transpiled circuit is compatible with the restricted parameter ranges accepted by the AQT API:
in the translation stage, the
WrapRxxAnglespass exploits the periodicity of theRXXGateto wrap its angle \(\theta\) to the \([0,\,\pi/2]\) range. This may come at the expense of extra single-qubit rotations.in the scheduling stage, single-qubit gates runs are decomposed as ZXZ products using Qiskit’s
OneQubitEulerDecompose, taking advantage of the virtual nature of the Z gate on AQT’s architecture. TheRewriteRxAsRpass subsequently rewritesRXGateoperations asRGate, wrapping the angle arguments to \(\theta\in[0,\,\pi]\) and \(\phi\in[0,\,2\pi]\)) in order to satisfy the AQT API constraints.
Transpilation in Qiskit primitives¶
The generic implementations of the Qiskit primitives Sampler and Estimator cache transpilation results to improve their runtime performance. This is particularly effective when evaluating batches of circuits that differ only in their parametrization.
However, some passes registered by the AQT transpiler plugin require knowledge of the bound parameter values. The specialized implementations AQTSampler and AQTEstimator use a hybrid approach, where the transpilation results of passes that do not require bound parameters are cached, while the small subset of passes that require fixed parameter values is executed before each circuit submission to the execution backend.
Circuit modifications behind the remote API¶
Circuits accepted by the AQT API are executed exactly as they were transmitted, with the only exception that small-angle \(\theta\) instances of RGate are substituted with
\(R(\theta,\,\phi)\ \to\ R(\pi, \phi+\pi)\cdot R(\theta+\pi,\,\phi)\).
The threshold for triggering this transformation is an implementation detail, typically around \(\theta=\pi/5\). Please contact AQT for details.
Common limitations¶
Reset operations are not supported¶
Because AQT backends do not support in-circuit state reinitialization of specific qubits, the Reset operation is not supported. The Qiskit transpiler will fail synthesis for circuits using it (e.g. through QuantumCircuit.initialize) when targeting AQT backends.
AQT backends always prepare the quantum register in the \(|0\rangle\otimes\cdots\otimes|0\rangle\) state. Thus, QuantumCircuit.prepare_state is an alternative to QuantumCircuit.initialize as first instruction in the circuit:
from qiskit import QuantumCircuit
qc = QuantumCircuit(2)
qc.initialize("01")
# ...
qc.measure_all()
is equivalent to:
from qiskit import QuantumCircuit
qc = QuantumCircuit(2)
qc.prepare_state("01")
# ...
qc.measure_all()