Fixes several RB issues. I still plan to write a few tests for these, but it is at least ready to review from the RB codeowners to ensure that these are good solutions to the features.
Deterministic Clifford compilation (#314)
The desire was to be able to do deterministic Clifford compilation when generating CliffordRBDesign objects. We actually already had a partial way to do this because the CliffordCompilationRules are more or less exactly this - a rule for how to build up a circuit from native gates that implement a Clifford. So my implementation is just to add a exact_compilation_key kwarg which uses the compilation rules to do this deterministic compilation when provided, and otherwise to do the previous behavior of synthesizing using the random algorithms.
An example:
import pygsti
from pygsti.processors import QubitProcessorSpec as QPS
from pygsti.processors import CliffordCompilationRules as CCR
n_qubits = 1
qubit_labels = ['Q'+str(i) for i in range(n_qubits)]
gate_names = ['Gi', 'Gxpi2', 'Gxpi', 'Gxmpi2', 'Gypi2', 'Gypi', 'Gympi2',
'Gzpi2', 'Gzpi', 'Gzmpi2', 'Gcphase']
availability = {'Gcphase':[('Q'+str(i),'Q'+str((i+1) % n_qubits)) for i in range(n_qubits)]}
pspec = QPS(n_qubits, gate_names, availability=availability, qubit_labels=qubit_labels)
compilations = {'absolute': CCR.create_standard(pspec, 'absolute', ('paulis', '1Qcliffords'), verbosity=0),
'paulieq': CCR.create_standard(pspec, 'paulieq', ('1Qcliffords', 'allcnots'), verbosity=0)}
depths = [0, 2]
k = 10
qubits = qubit_labels
This will create the design as before, with random Clifford synthesis:
The CliffordRBDesign now keeps track of how many native gates are in the first length+1 Cliffords, i.e. excluding the inversion Clifford, stores them in a native_gate_count_lists member variable, and provides convenience functions to compute the averages.
design = pygsti.protocols.CliffordRBDesign(pspec, compilations, [0, 2], 5, qubit_labels=qubits,
randomizeout=False, citerations=10)
design.native_gate_count_lists # A list of lists of the number of native gates for the compiled Cliffords (without inversion)
design.average_native_gates_per_clifford() # Compute average over all circuits
As an aside, I also added a num_gates utility function to Circuit that was apparently missing. There was num_nq_gates and num_multiq_gates so you could have done num_nq_gates(1) + num_multiq_gates, but might as well provide it.
Truncation bugfix for RBDesigns (#408)
The various BenchmarkingDesign classes often have lists that are intended to be paired with the circuit_lists member attribute. These paired attributes were not being truncated properly.
To fix this, the BenchmarkingDesign now has a paired_with_circuit_attrs member variable which lists the names of any attribute that is intended to correspond 1-to-1 with the circuit_lists. During truncation, these paired attributes are zipped up with the circuits during filtering, and then unzipped into the new truncated lists. Paired attributes are also serialized separately to JSON files, as we often want to look at them independently.
A currently exhaustive list of paired attributes (paired attributes propogate to derived classes):
BenchmarkingDesign: idealout_lists
CliffordRBDesign: num_native_gate_lists (due to the #315 fix above)
Fixes several RB issues. I still plan to write a few tests for these, but it is at least ready to review from the RB codeowners to ensure that these are good solutions to the features.
Deterministic Clifford compilation (#314)
The desire was to be able to do deterministic Clifford compilation when generating
CliffordRBDesign
objects. We actually already had a partial way to do this because theCliffordCompilationRules
are more or less exactly this - a rule for how to build up a circuit from native gates that implement a Clifford. So my implementation is just to add aexact_compilation_key
kwarg which uses the compilation rules to do this deterministic compilation when provided, and otherwise to do the previous behavior of synthesizing using the random algorithms.An example:
This will create the design as before, with random Clifford synthesis:
This will create a design using the
absolute
compilation of each Clifford instead:Or similarly, we could do a compilation up to Pauli equivalence with the
paulieq
compilation:A non-standard compilation rule could also be done:
Native gate per Clifford statistics (#315)
The
CliffordRBDesign
now keeps track of how many native gates are in the firstlength
+1 Cliffords, i.e. excluding the inversion Clifford, stores them in anative_gate_count_lists
member variable, and provides convenience functions to compute the averages.As an aside, I also added a
num_gates
utility function toCircuit
that was apparently missing. There wasnum_nq_gates
andnum_multiq_gates
so you could have donenum_nq_gates(1) + num_multiq_gates
, but might as well provide it.Truncation bugfix for RBDesigns (#408)
The various
BenchmarkingDesign
classes often have lists that are intended to be paired with thecircuit_lists
member attribute. These paired attributes were not being truncated properly.To fix this, the
BenchmarkingDesign
now has apaired_with_circuit_attrs
member variable which lists the names of any attribute that is intended to correspond 1-to-1 with thecircuit_lists
. During truncation, these paired attributes are zipped up with the circuits during filtering, and then unzipped into the new truncated lists. Paired attributes are also serialized separately to JSON files, as we often want to look at them independently.A currently exhaustive list of paired attributes (paired attributes propogate to derived classes):
BenchmarkingDesign
:idealout_lists
CliffordRBDesign
:num_native_gate_lists
(due to the #315 fix above)BinaryRBDesign
:measurements
,signs