-
Notifications
You must be signed in to change notification settings - Fork 57
Mirror circuit fidelity estimation support and introduction of benchmarking interface (name TBD) #628
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…pytket import since it is no longer needed
… uses a more reasonable test-ref match verification
…re reference circuit does not use ancillae, other changes
Quick note: I expect to be able to merge in #379 tomorrow morning. Once that is on develop I'll ping you and then let's merge develop into your branch to use as the baseline for reviewing. This will knock out a decent number of changes and reduce any redundancy. |
Update: #379 is now merged into develop. It looks like there might be a couple conflicts to resolve when merging develop into your branch, so hopefully those won't be tricky. I'll start my review once that merge is done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file was identical to run_me_with_mpirun.py
.
Merged in develop and fixed a couple of minor things. @coreyostrove, should be ready for your review. |
…t sample in the same width/depth
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a true tour-de-force, thanks for the massive amount of effort that went into the development of these new capabilities, @ndsieki!
I have made a few suggestions and requests inline. Nothing that constituted a major concern as I recall (your set of unit tests looked rather comprehensive, which goes a long way to assuaging any concerns), and hopefully these should be fairly quick to enact. Please see in line comments, but a couple high-level recurring themes:
- Please take a pass through the new code and give it a spring cleaning. I noticed a large number of commented out print statements (presumably from debugging and development), older/obsolete implementations, etc. If you could identify the stragglers which are no longer needed that'd be great.
- Move try-except blocks into relevant functions, specifically for the qiskit and matplotlib imports. The rationale here is that not everyone will have qiskit installed, and most of the time that is fine, we should only raise warnings when touching functionality that requires it.
Also, we'll want to make sure all of your unit tests are passing. As of last night they weren't but it looks like you recently pushed some changes which may have addressed those.
Overall this all looks good though. Sorry it took a while to review (there was a lot of code here, in my defense). Ping me when you've had a chance to implement these changes and I strongly suspect we'll be good to go at that point to fully approve and merge this in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is hard to add this comment inline, but you have a cell in this example notebook under the heading "Compute process fidelity for each circuit" which contains a bunch of postprocessing functions which ultimately return a pandas dataframe with the estimate process fidelities. Is the functionality of these helper function implemented in pyGSTi proper? You mentioned in the PR notes a new method for VBDataFrame which sounded like it would superficially produce a comparable output to your helper functions.
@@ -1893,7 +1893,7 @@ def to_native(self): | |||
""" | |||
return tuple(self) | |||
|
|||
def replacename(self, oldname, newname): | |||
def replace_name(self, oldname, newname): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch!
pygsti/baseobjs/qubitgraph.py
Outdated
@@ -878,7 +878,7 @@ def subgraph(self, nodes_to_keep, reset_nodes=False): | |||
qubit_labels = nodes_to_keep | |||
|
|||
edges = [] | |||
for edge in self.edges(): | |||
for edge in self.edges(include_directions=True): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, can you add this kwarg to subgraph (defaulted to True, for the reasons you've stated) and plumb this through?
pygsti/circuits/circuit.py
Outdated
if qiskit.__version__ != '2.1.1': | ||
_warnings.warn("Circuit class method `from_qiskit()` and method `convert_to_qiskit`" | ||
"is designed for qiskit version 2.1.1 and may not \ | ||
function properly for your qiskit version, which is " + qiskit.__version__) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should revisit down the line whether to either revise this warning to include a broader range of acceptable versions as this gets tested with newer versions of qiskit, or if it is really important we're on a specific qiskit version lets pin that in the pyGSTi requirements.
pygsti/circuits/circuit.py
Outdated
@@ -22,6 +25,16 @@ | |||
from pygsti.tools import slicetools as _slct | |||
from pygsti.tools.legacytools import deprecate as _deprecate_fn | |||
|
|||
try: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's move the try except block for the qiskit import into the definitions of from_qiskit
and convert_to_qiskit
. And with that being done have the except block actually raise that ImportError (with your additional context information), as at that point the failure of the import is critical.
pygsti/protocols/mirror_edesign.py
Outdated
"'qiskit_circuits_to_fullstack_mirror_edesign', and" \ | ||
"'qiskit_circuits_to_subcircuit_mirror_edesign are designed for qiskit 2.1.1. Your version is " + qiskit.__version__) | ||
|
||
from qiskit import transpile |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar comment to the previous ones related to this try-except block. Let's move these into the qiskit_* functions, as the core make_mirror_edesign
doesn't rely on this, and we don't want to raise warnings for everyone if they're not using the qiskit functionality.
pygsti/protocols/vbdataframe.py
Outdated
import matplotlib.pyplot as _plt | ||
import matplotlib as _mp | ||
except: | ||
_warnings.warn('matplotlib is required for dataframe plotting, and does not appear to be installed.') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move this into create_vb_plot
pygsti/tools/bsqale.py
Outdated
Please see <paper link forthcoming> for more information. | ||
""" | ||
|
||
# TODO: add copyright assertion |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add this.
pygsti/tools/bsqale.py
Outdated
"'qiskit_circuits_to_fullstack_mirror_edesign', and" \ | ||
"'qiskit_circuits_to_subcircuit_mirror_edesign are designed for qiskit 2.1.1. Your version is " + qiskit.__version__) | ||
from qiskit import transpile | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See previous comments on moving these try and excepts to the relevant functions reliant on qiskit.
pygsti/tools/internalgates.py
Outdated
if qiskit.__version__ != '2.1.1': | ||
_warnings.warn("function 'standard_gatenames_qiskit_conversions()' is designed for qiskit version 2.1.1 \ | ||
and may not function properly for your qiskit version, which is " + qiskit.__version__) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See previous comments regarding the qiskit try-except blocks.
if verbosity > 0: | ||
print(f'Found subcircuit with {total_dropped_gates} dropped gates, {compiled_depth} depth, and {total_dangling_gates} dangling gates') | ||
|
||
if (failures == 1000): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be a variable global to the file which can be modified if the user is willing to wait longer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good suggestion. A standard practice in that case is to name it using all caps, and to give it an evocative name unlikely to result in namespace conflicts. something like MAX_STARTING_LAYER_ATTEMPTS
.
…tions, remove debug commented code
@coreyostrove, I've made the changes you requested (along with those suggested by @nkoskelo). Please let me know if I missed anything, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything here looks good as far as I am concerned, thank you for your effort addressing all of the suggestions and requests. @tjproct is going to try to give this a quick once-over to try and catch any possible MCFE math-related bugs, which I am less well-suited to do on my end. Once we've gotten the thumbs-up from him I'll officially mark this as approved and we can get it merged in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have only given the code a brief review due to time constraints right now. It looks good to me. I suspect that we may want to, in the future, rename some functions and do bits and pieces of minor restructuring / removing redundancy with other benchmarking code (e.g., I think there might be redundancy with data analysis code used for mirror RB). However, I think it makes sense to accept this now, and to update the code when we have time in the future (and prior to final publication of Noah's paper that's based around this code). In particular, I (personally) anticipate spending some time in the fall revamping the broader pyGSTi benchmarking code as part of developing some new benchmarks + merging in some hacked-together new benchmarking capabilities that currently exist on a feature branch. During that process it would likely make sense to make small tweaks to this code and remove redundancies at that point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR adds a benchmark creation tool we are calling B-Sqale (for the time being), integrates mirror circuit benchmarking into pyGSTi, and improves Qiskit interfacing.
Circuit mirroring functionality is supported by:
RandomCompilation
class, which OOP-ifies both the central Pauli (https://www.nature.com/articles/s41567-021-01409-7) and random compilation (https://arxiv.org/abs/2204.07568) mirroring routines.pygsti.protocols.mirror_edesign
. The core routine ismake_mirror_edesign
, which creates aCombinedExperimentDesign
whose circuits can be executed to perform mirror circuit fidelity estimation (MCFE). There are three other functions -qiskit_circuits_to_mirror_edesign
,qiskit_circuits_to_fullstack_mirror_edesign
, andqiskit_circuits_to_subcircuit_mirror_edesign
- which build onmake_mirror_edesign
to create different kinds of benchmarks directly from Qiskit circuits.from_mirror_experiment
class method for theVBDataFrame
class, which streamlines the analysis process for MCFE. TheVBDataFrame
class also now includes plotting functionality for creating volumetric benchmarking plots from subcircuit mirror experiments.This PR also adds B-Sqale (name subject to change), a scalable and robust benchmark creation tool, to pyGSTi. More information will be available in a forthcoming paper. The submodule
pygsti.tools.bsqale
provides wrappers for the mirror benchmarking functionality:noise_mirror_benchmark
(wrapper forqiskit_circuits_to_mirror_edesign
)fullstack_mirror_benchmark
(wrapper forqiskit_circuits_to_fullstack_mirror_edesign
)subcircuit_mirror_benchmark
(wrapper forqiskit_circuits_to_subcircuit_mirror_edesign
)calculate_mirror_benchmark_results
(wrapper forVBDataFrame.from_mirror_experiment
)These wrappers are provided in anticipation of expanding B-Sqale to scalable benchmarking techniques beyond MCFE.
Interfacing with Qiskit is supported by the addition of a
from_qiskit
class method andconvert_to_qiskit
method to theCircuit
class.