1. Pipeline and utility tools for parallel benchmarking¶
1.1 Benchmark circuits¶
Included are a suite of benchmark circuits, useful for examples, getting started, and benchmarking; and include, * Bell state circuit/state * 3 and 4 qubit GHZ circuit/state * 3 and 4 qubit linear cluster states
1.2 Benchmark graph states¶
We also include a suite of benchmark graph states.
""" Random connected graph state """
# NOTE that this function optionally takes a random number generator (rng) object
# An rng with a specific should ALWAYS be specified when benchmarking such that
# results are replicable
import numpy as np
from graphiq.benchmarks.graph_states import random_graph_state
n_qubits = 10
# Sparse circuit
prob_edge = 0.1 # this is the probability of an edge (ignoring edges necessary for connectedness)
rng = np.random.default_rng(4)
random_graph_state(n_qubits, prob_edge, rng).draw()
# Dense circuit
prob_edge = 0.9 # this is the probability of an edge (ignoring edges necessary for connectedness)
rng = np.random.default_rng(4)
random_graph_state(n_qubits, prob_edge, rng).draw()
1.2.1 Local Clifford equivalence¶
Local Clifford (LC) equivalence is significant in graph states, because local complementation tends to be easy to implement in quantum computing. Thus, if we can find a state which is LC equivalent to another, we can also easily find the other state. Thus, we provide a functionality to generate LC equivalent states, from a starting circuit using random_lc_equivalent (see docstring). This could be useful, for example, for determining whether all LC equivalent states are equally easy to find or not (given a specific solver).
1.3 Benchmark: Utils and Pipeline¶
Our benchmarking pipeline help manage different solver runs, and mediates the information collection, data saving, and multi-core computing distribution.
benchmark_utils.py was used for earlier data collection, but pipeline.py should be used for most future benchmarking tasks. It allows our code to run on multiple cores through a python package called ray.
A good example of how to use the pipeline is in the __main__ function of pipeline.py, so we won't duplicate the example here.
1.3.1 Functions offered by pipeline.py¶
metadata(): collects a data dictionary about the machine running the testsrun_combinations: allow us to generate all possible combinations different combinations of solvers/targets/compilers/target metrics, and returns a list of dictionaries, each capable of being used for a benchmark runbenchmark_run: benchmarks a single solver runbenchmark: benchmarks a sequence of runs
1.3.2 Data generated in benchmark runs¶
- Machine metadata
- Runtime of a benchmark run
- Generated populations / halls of fame (circuits expressed as openQASM)
- Solver logs at each iteration, for both the population and hall of fame (include interation number, statistics for the cost function cost, statistics for the circuit depths)
- Class / information about the solver, compiler, etc.
1.3.3 Benchmarking consideration: measurement results and probabilistic effects¶
One word of warning about solver data.
We have probabilistic events occurring in our circuit simulation. Currently, we do not evaluate circuits multiple times in the solver. This means that the cost functions noted in the per-iteration logs are dependent only on one run, even if they might have failed in another run.
For example, a circuit may generate the correct output state if a Z measurement on emitter 0 returns 1, and return an incorrect output state otherwise. This is not reflected in our solver data.
Thus, before deciding a given circuit design is optimal, we should either test all possible measurement combinations (there are 2^n possible combinations for n measurements which lead to probabilistic gate application), or probabilistically simulate the circuit repeatedly and see whether its output is consistent.
It may useful to add some benchmarking functionality to that effect, in the future.
NOTE: the function circuit_measurement_independent in benchmark_utils.py was used for this purpose in earlier tests. However, it is only guaranteed to work in cases where only 1 probabilistic gate application.