Add Mirror RB experiment#842
Conversation
gadial
left a comment
There was a problem hiding this comment.
Generally looks great, there are some small issues that needs addressing.
| if self._inverting_pauli_layer: | ||
| for circuit in circuits: | ||
| target = circuit.metadata["target"] | ||
| label = "".join(["X" if char == "1" else "I" for char in target]) |
There was a problem hiding this comment.
I have to admit I don't understand what's going on here.
There was a problem hiding this comment.
Added comments, please let us know if it makes sense now
…ircuits, comment pauli label
| illustrate, consider the two circuits below, both of which were generated in | ||
| ``pyGSTi``. The first circuit was transpiled in ``pyGSTi``, | ||
|
|
||
| .. image:: pygsti-data-pygsti-transpiled-circ.png |
There was a problem hiding this comment.
Why this cannot be generated here? You have hidden cell option.
There was a problem hiding this comment.
pyGSTi is required to generate these circuits, and we don't want to require pyGSTi to accurately render the documentation.
| """ | ||
|
|
||
| # Backend must have a coupling map | ||
| if not self._backend or not self._backend.configuration().coupling_map: |
There was a problem hiding this comment.
Hmm... I understand why we need this check here. Basically MirrorRB can target more than 2Q, then we should avoid applying 2Q gate to non-adjacent qubits otherwise extra SWAP is required.
On the other hand, the standard execution model of QE for now is
- define circuit in the virtual qubit domain
- call transpiler with initial layout, which is based on the experiment's physical qubits
- run circuit in the physical qubit domain (transpiled circuit) on the target backend.
and this experiment intentionally avoids step 1 due to above constraint. This probably motivate us to turn the backend in the experiment class constructor into required (currently it's optional), and to deprecate another backend argument in the BaseExperiment.run method. This model indicates an experiment instance is always aware of the target backend, and we can reasonably generate circuits on top of some hardware architecture constraints -- as you are doing in this PR.
There was a problem hiding this comment.
I see, the reason why we added this check instead of making the backend required is because @chriseclectic and @coruscating had mentioned that backends aren't serializable, so it may be better to keep it optional and only check for it when the circuits are being generated. Considering these points, what would be the best option here?
There was a problem hiding this comment.
I lean toward having backend in the constructor as required because this benefits other experiments as well (e.g. T1 experiment needs to check timing constraints to build circuits). I think we should add special handling for backend in serialization/deserialization (I think it's enough to keep backend name instead of serialized object and ask user to set identical backend if the experiment is loaded instance).
There was a problem hiding this comment.
We discussed several potential plans for handling this in the meeting. @nkanazawa1989 are you okay with keeping the current implementation for this experiment and merging first, and then working on changing the implementation in a future PR?
| # Backend must have a coupling map | ||
| if not self._backend or not self._backend.configuration().coupling_map: | ||
| raise QiskitError( | ||
| "Must provide a backend with a coupling map or provide " |
There was a problem hiding this comment.
If a coupling map is not provided, you can generate all possible combination instead. Such data can be easily generated with itertools.
|
|
||
| # Store transpiled circuits in metadata | ||
| for circ in transpiled: | ||
| circ.metadata["transpiled_qiskit_circ"] = circ |
There was a problem hiding this comment.
This will break QPY serialization I guess unless you provide custom Json serializer.
There was a problem hiding this comment.
We've moved this to a PR in the internal repository
| full_sampling: bool = False, | ||
| inverting_pauli_layer: bool = False, | ||
| ): | ||
| """Initialize a mirror randomized benchmarking experiment that uses |
There was a problem hiding this comment.
What is the benefit of this class for users? If this class is just for validation, you should extract the circuit generation logic and use it only in the unittest to compare the output circuits. If PyGSTi gives you something like x10 performance improvement, perhaps it's worth having it here, but not as a subclass. You can refer to the implementation of tomography module. There are several fitters available (numpy, scipy, cvxopt) but these are the single class and the internal logic is dynamically switched based on the analysis option. Something like this would work.
There was a problem hiding this comment.
We plan to make a separate PR for moving this class to the internal repository.
|
Would it be better to report error per layer instead of EPC? Especially since there will be non-Clifford and Clifford versions. |
|
@coruscating Yeah that would be more accurate |
|
I think this can be merged after addressing Naoki's comments and changing EPC to EPL. If issues come up later, those can be addressed in future PRs. |
|
The term "EPC" is currently used in standard and interleaved RB, so it would have to be replaced in those implementations too. Or maybe it would be better to replace "EPC" with "EPL" in the PR with universal-gate-set MRB. This PR implements MRB with circuits generated by the "old" sampling method which, to my knowledge, has only been implemented with Clifford gates. |
|
Agreed, let's leave it as EPC for this PR then. |
|
Assuming the branch
|
ihincks
left a comment
There was a problem hiding this comment.
I am very happy to see this PR as I think Mirror RB will a great asset to experiments!
My biggest concern with this PR is that MirrorRB, as implemented, doesn't let users specify the layers to use or the distribution over them, which is arguably the biggest selling point of mirror RB. Instead, the layers and the distribution are chosen by random_edgegrab_clifford_circuits. This assumption is baked into the API, so that generalizing MirrorRB to more diverse distributions would likely require a breaking change. To be clear, my main concern is the API; I think that using random edges is a very good thing to include in a first release, and also a very sensible default.
I suggest looking into whether the distribution itself could be an argument to the experiment, with random_edgegrab_clifford_circuits being one possible value. The distribution could be a callable returning layers, or something.
I have left a few other comments which, relative to the above, I view as being minor.
Among these comments, I'd just like to highlight that the experiment in a few places is described as being "more scalable" and also that "it can be used to detect crosstalk errors". I think the former statement is often worded to not give enough credit to other scalable characterization protocols that came before it, though I realize that (I think) the intent is to compare it only with standard randomized benchmarking using huge Cliffords. The latter statement, while true, I think is a bit narrow to be emphasized so heavily. Mirror RB at its core is for estimating fidelities marginalized over distributions of layers, and using several experiments to infer information about crosstalk is just one particular application of this ability.
| .. ref_website:: qiskit-experiments, https://github.com/Qiskit/qiskit-experiments | ||
|
|
||
| """ | ||
|
|
There was a problem hiding this comment.
The changes to this file look unnecessary; please revert them if so.
| A new experiment class :class:`qiskit_experiments.library.MirrorRB` is | ||
| introduced. This class implements mirror randomized benchmarking (RB), a version | ||
| of RB that uses mirror circuits. It is more scalable than other RB protocols and | ||
| can consequently be used to detect crosstalk errors. |
There was a problem hiding this comment.
There are many scalable RB protocols (direct fidelity estimation, cycle benchmarking, xeb, etc), so I think we sholud be a bit careful about the blanket statement "It is more scalable than other RB protocols". I suggest:
A new experiment class :class:`qiskit_experiments.library.MirrorRB` is
introduced. This class implements mirror randomized benchmarking (RB), which is a protocol
that measures the fidelity of user-defined ensembles of randomized mirror circuits.
| @@ -41,8 +41,8 @@ | |||
| "outputs": [], | |||
| "source": [ | |||
| "IBMQ.load_account()\n", | |||
There was a problem hiding this comment.
The changes to this file look unnecessary; please revert them if so.
| @@ -40,8 +40,8 @@ | |||
| "outputs": [], | |||
| "source": [ | |||
| "IBMQ.load_account()\n", | |||
There was a problem hiding this comment.
The changes to this file look unnecessary; please revert them if so.
| Args: | ||
| qubits: A list of physical qubits for the experiment. | ||
| lengths: A list of RB sequences lengths. | ||
| local_clifford: If True, begin the circuit with uniformly random 1-qubit |
There was a problem hiding this comment.
What value do the optional "local_clifford" and "pauli_randomize" bring to this experiment?
| Mirror RB experiment | ||
| -------------------- | ||
|
|
||
| Mirror RB is a RB protocol that is more scalable to larger numbers of qubits, |
There was a problem hiding this comment.
I think that "more scalable" needs to be qualified a bit, and that crosstalk detection needs to be discussed as an application of the protocol rather than a central aspect. Indeed, standard randomized benchmarking in parallel can do some types of crosstalk detection.
Summary
Added mirror randomized benchmarking experiment and analysis classes
Details and comments
TODO
Accommodate mirror circuits of zero length