Skip to content

Mirror Benchmarking

Introduction

Mirror Benchmarking (MB) is a noise benchmarking method that works as follows: one prepares a state, performs the circuit, followed by its inverse, then measures the result. Ideally, the system returns to its initial state. However, due to gate errors, this is not guaranteed. The result of the test is the success probability, which is the probability we arrive at the initial state. Including the state preparation in the circuit \(G\), it is given by

\[ p\left(G\right) = \langle 0| \mathcal{E} \left(G ^ \dagger\right) \mathcal{E} \left(G\right) | 0 \rangle \]

This technique is inspired by similar approaches with random circuits referred to as Mirror Benchmarking or Mirror Circuit Benchmarking [1-2]. To leverage the full capabilities of Classiq's synthesis engine, MB is done on a functional level model, rather than a low-level circuit, enabling application-oriented benchmarking. That way, hardware-aware synthesis is possible, making sure the program is optimized for each hardware, and that the test indeed measures how well the hardware suites a specific program.

Usage

To use the MB package, simply import the MirrorBenchmarking object, and construct it from a model. The object has a synthesize method, and code execution is the same as in any other circuit.

from classiq.applications.benchmarking import MirrorBenchmarking

circuit = MirrorBenchmarking(model_designer).synthesize()

Example

The following example contains code performing a MB test on the IBM Quantum's "Quito" device, with hardware settings defined automatically for the device. The measured success probability is 11.65%. Note that to run the example ACCESS_TOKEN must be assigned a valid value.

from classiq.interface.backend import backend_preferences
from classiq.interface.generator.model.preferences.preferences import Preferences
from classiq.interface.generator.qft import QFT

from classiq import Executor, MirrorBenchmarking, ModelDesigner

model_designer = ModelDesigner(
    preferences=Preferences(
        backend_service_provider="IBM Quantum", backend_name="quito"
    )
)

num_qubits = 5
qft_params = QFT(num_qubits=num_qubits)
model_designer.QFT(qft_params)

circuit = MirrorBenchmarking(model_designer).synthesize()
program = circuit.to_program()

res = Executor(
    num_shots=10000,
    backend_preferences=backend_preferences.IBMBackendPreferences(
        backend_name="ibmq_quito", access_token=ACCESS_TOKEN
    ),
).execute_quantum_program(quantum_program=program)
counts = res.counts

success_probability = counts["0" * num_qubits] / sum(counts.values())
print(success_probability)

References

[1] T. Proctor, K. Rudinger, K. Young, E. Nielsen, R. Blume-Kohout, "Measuring the capabilities of quantum computers". Available: https://www.nature.com/articles/s41567-021-01409-7

[2] K. Mayer, A. Hall. T. Gatterman. S. K. Halit, K. Lee, J. Bohnet, D. Gresh, A. Hankin, K. Gilmore, J. Gerber, J. Gaebler, "Theory of mirror benchmarking and demonstration on a quantum computer". Available: https://arxiv.org/pdf/2108.10431.pdf