-
Notifications
You must be signed in to change notification settings - Fork 58
Leakage-aware GST #410
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
Leakage-aware GST #410
Conversation
f422726 to
2f23347
Compare
|
EDIT: we now have an open issue about handling this sort of thing #633. Text from an email Piper sent (not showing plots since they contained real data):
I think the solution here is just to make sure that the first iteration of leakage-aware GST uses L=2 instead of L=1. (Or, more generally, we use the smallest L where N_s > N_p.) |
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.
Leaving file-level comments so @coreyostrove and I can figure out what to split out from this PR.
…inearOperator (not just plain numpy ndarrays)
…frobenius norm computation. Bugfix in test_optools.py.
…lots of in-line comments explaining the logic.
…anch that omitted jac as a keyword argument to scipy.minimize, even if jac was None.
…nt fidelity from the calculation of that metric itself. This makes it easier to reuse the setup code in other metrics. While making this change, also make the setup more efficient by using TensorProduct bases from the beginning.
…imizers. Right now only entanglement fidelity and jtracedist have implementations that can consider leakage. (So there are no leakage-aware metrics for SPAM.)
…dded annotations to all gauage optimization objectives used in the non-LS optimizer, indicating if that particular objective has support for leakage-aware metrics.
… while. The tests only consider when no leakage is modeled. New tests wil be needed for when theres a leakage dimension
This isn’t a uniquely leakage-related shortcoming, I’ve encountered this in other settings too (with really aggressive FPR schemes when not forcing inclusion of LGST circuits, for example) and I suggest we open up a separate github issue for this and give some additional thought to how we should be approaching the statistics in this case. |
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.
Just finished my first pass through. This is a ton of effort and these contributions are sincerely appreciated. Thank you as always for the excellent work, @rileyjmurray!
Of the comments I've left, the only one I am deeply concerned about is the potential bug that I've pointed out in the cost function for gauge optimization as it pertains to instruments. I have good reason to suspect (I mean, the git history is pretty clear and this present on develop so it isn't really a suspicion) that in the event there is a bug here it is very likely you had nothing to do with introducing it, but since you're already knee deep in this code I'd ask that you take a look and if necessary clean this up on our behalf.
Rest of my comments are either minor clarifying questions or otherwise nice-to-have but non-blocking requests. I've also added my concurrence with a couple comments/suggestions from @nkoskelo.
pygsti/algorithms/gaugeopt.py
Outdated
| assert gates_metric != "frobeniustt" | ||
| assert spam_metric != "frobeniustt" | ||
| # assert spam_metric == gates_metric | ||
| # ^ Erik and Corey said these are rarely used. I've removed support for | ||
| # them in this codepath (non-LS optimizer) in order to make it easier to | ||
| # read my updated code for leakage-aware metrics. It wouldn't be hard to | ||
| # add support back, but I just want to keep things simple. -- Riley |
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 an error message for the AssertionError indicating that these metrics are not supported when doing leakage-aware gauge optimization (i.e. n_leak>0).
| elif self._static and x._static and self._hash != x._hash: | ||
| return False | ||
| else: | ||
| if self._static and x._static: | ||
| return self._hash == x._hash | ||
| else: | ||
| return self.tup == x.tup | ||
| return self.tup == x.tup |
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.
These look functionally equivalent to me. I’ll take your word for it, but for my own edification what about the original version was incorrect?
| opLabels = set() | ||
| empty_label = _Label(()) | ||
| for circuit in self: | ||
| for layer in circuit.layertup: |
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 and I think it would be an independently useful primitive for circuits to return their unique gate labels, probably with some flags to control matching behavior (e.g. just label names versus full labels with sslbls).
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 looks like most/all of these reportable functions hard code in that n_leak is one. I don't think there is anything to flag a user specifying something different in construct_standard_report, though. That is fine for now, but maybe add an assertion for this to avoid unexpected behavior? (i.e. a user being confused by why this was quietly changed under the hood).
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 point. I'll update the construct_standard_report docstring and raise an exception if the user passes in n_leak other than 0 or 1.
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 one I left on the leakage model regarding docstrings and API-level.
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'm going to say that everything here is in the private API for now.
… suppression we do in sdptools.py)
… a result. Type annotations, docs, and streamlined implementation of frobeniusdist_squared in linearop.py, effect.py, and state.py.
…ix bugs introduced in the last couple of commits.
|
@coreyostrove I think I've addressed your comments. Just pushed what should be the last round of changes. |
I think the only major outstanding concern here is the bug I alluded to with gauge optimization for instruments. Since this is a pre-existing bug I am alright with tabling this for the purposes of this PR, but we should open up a new github issue to track it. If you have time today can you open this issue? If not I can do so myself later this evening. |
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.
Fantastic work, @rileyjmurray! Thank you for the significant effort this work represents and your contributions advancing our leakage modeling capabilities. Merge at will.
One last request as you merge things in, can you flesh out the summary in the PR? That’d be helpful as I prepare release notes (and for posterity).
|
The single failing test is caused by implementation details of /test/unit/mpi/test_mpi.py::MPITester::test_all. Merging as-is. |
This PR significantly expands pyGSTi's leakage modeling capabilities.
Note. This PR description was written after Corey's approval and a few follow-up commits from me.
Important stuff in new files
jupyter_notebooks/Examples/Leakage_automagic.ipynb. This illustrates how data from a 1-qubit GST experiment can be used to fit a 1-qutrit model, and how to generate reports that include leakage analysis of that 1-qutrit model.
pygsti/tools/leakage.py. I've divided this file into four regions.
construct_leakage_report, which handles gauge optimization and report generation. It returns a Report object and an updated ModelEstimateResults object.n_leak=1when a user callsconstruct_leakage_report. Users are also free to call these functions themselves.leaky_qubit_model_from_pspec, which creates a three-level ExplicitOpModel by lifting a qubit processor spec.add_lago_modelsis particularly user-facing. It adds additional "leakage-aware gauge optimized" or "LAGO" models to the provided ModelEstimateResults object. It's called automatically inconstruct_leakage_report.pygsti/tools/sdptools.py. This has pyGSTi's semidefinite programming modeling code. Some of its contents were pulled from pygsti/tools/optools.py. Much of its contents are new. The
diamond_distance_projection_modelfunction lets us compute a superoperator's diamond-distance projection onto certain convex sets of superoperators (namely, any intersection of the sets of CPTP operators, leakage-free operators, and seepage-free operators); this same function lets us compute the projection with respect to the standard diamond norm and a "subspace" diamond norm.Overview of API changes in existing files
Things with higher user-exposure
Calling
b = BuiltinBasis('l2p1', 9)gets you a special leakage basis for nine-dimensional Hilbert-Schmidt space.The basis reflects a canonical separation of its underlying Hilbert space into a direct sum of a 2-dimensional space and a 1-dimensional space. In the future we extend this to
l{x}p{y}for integersx >= 2andy >= 1.pygsti/models/explicitmodel.py has a new free function:
which uses ComposedOp, ComposedState, and ComposedPOVM to build a gauge-transformed copy of
mdlthat has the same parameterization asmdl.The
jamiolkowski_isoandinv_jamiolkowski_isofunctions in pygsti/tools/jamiolkowski.py can now operate on CVXPY Expression objects. Separately, all Jamiolkowski functions in this file new accept an optionalnormalizedargument that defaults to True, indicating if we're working with the normalized (inverse) Choi matrix.The LazyBasis class (which is a parent of BuiltinBasis) has a new member called
elindlookup. This is a lazily-constructed dict whereis the basis element corresponding to
element_label.Our LinearOperator class (a subclass of ModelMember) now has a
.shapeparameter, in order to provide API similarity with common Python array types.Things with low user-exposure that could be higher
I added several new functions to pygsti/report/reportables.py. Nearly all of these functions also has a class representation generated by the
opfn_factoryfunction from pygsti/report/modelfunction.py. The descriptions of these functions can be found in the docstring and implementation ofinfo_of_opfn_by_name. Functions that appear in pygsti/tools/leakage.py have their own documentation. I'm leaving it to future work to include all leakage-related metrics in pygsti/tools/leakage.py.Things with low exposure that should stay that way
The ConfidenceRegionFactoryView class has a new instance method called
compute_grad_f. This is for computing the gradient of a ModelFunction object at a given point. Evaluatingcompute_grad_fconstitutes most of the work in a call to ConfidenceRegionFactoryView.compute_confidence_interval.pygsti/tools/matrixtools.py has a new class called
IdentityOperator. Objects of this class implement@,.T, and.conj()as though they were numpy ndarrays. However, these operations are "no-ops," and so cost basically nothing. This class is used in new gauge optimization code. It comes with a free function calledis_operatorlikefor checking if something can plausibly be used as a linear operator with a numpy-like API.The gaugeopt_to_target function in pygsti/algorithms/gaugeopt.py accepts an
n_leakargument that's a nonnegative integer and that defaults to 0. Choices ofn_leak > 0cannot be used with the default optimizer ("ls"); one should request"L-BFGS-B"instead.The instance method
ExplicitOpModelCalc.frobeniusdistnow has a different behavior for thetransform_mxargument. You can pass in None or an ndarray (as in previous code) or you can pass in a pair of objects wherematrixtools.is_operatorlike(obj)returns True.Other notes
We now test for correctness of gauge optimization code in test/unit/algorithms/test_gaugeopt_correctness.py. Old tests (which were just smoke tests) were moved to test/unit/algorithms/test_gaugeopt_noerrors.py.
The code in the "Leakage-automagic" example notebook is run as a smoke test in test/unit/tools/test_leakage_gst_pipeline.py.
Some tests were added to test/unit/tools/test_optools.py.
Unresolved comments:
*https://github.com/sandialabs/pyGSTi/pull/410/files#r2255546335 (request for test to trigger a new error handling codepath).
Future work: