Skip to content
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

Update/New Cirq Parsing Capabilities #411

Merged
merged 12 commits into from
Apr 2, 2024

Conversation

coreyostrove
Copy link
Contributor

This PR updates the existing parser for conversion of pyGSTi Circuit objects to Cirq Circuit objects. Also introduced is a new parser for converting from Cirq Circuits objects into pyGSTi Circuit objects. A few other minor changes include:

  1. Updates to pyGSTi's built-in gate definitions to include the following:
  • 'Giswap' and 'Gsqrtiswap' (2-qubit gates commonly used on superconducting platforms)
  • 'Gcres' and 'Gecres' (2-qubit cross-resonance and echoed cross-resonance gates, respectively, native on many platforms including IBM's)
  • 'Gn' (one-qubit N gate, a pi/2 rotation about the (np.sqrt(3)/2, 0, -1/2) axis of the Bloch sphere, commonly used native gate in some silicon qubit platforms, the N referred to in the smq1Q_ZN modelpack),
  • 'Gxpi4', 'Gypi4', 'Gzpi4' (pi/4 rotations above the various Bloch sphere axes, Gxpi4 appeared in one of the modelpacks, and I figured it best to add the Y and Z counterparts at the same time).
  1. Updated the function unitary_to_standard_gatename in tools.internalgates to allow the option for checking for equivalence of unitaries to a built-in gate up to an overall global phase.

  2. New unit tests (including one for qasm conversion, which was previously not unit tested) and updates to the cirq integration demo notebook to include the new functionality.

Note: I branched this off of #403, which is why there is so much testing update stuff in the commit log (once that gets merged in it should go away from this PR), stuff relevant to this update begins 3/13/24 w/ 185a59a.

Corey Ostrove added 9 commits March 13, 2024 20:47
Adds a few new built-in gate names along with their corresponding unitaries. Extends the default built-in cirq conversion dictionary to include the 24 single-qubit clifford gate names, along with a few other one and two-qubit gates that did not have support yet.
Fix the docstrings in a few modelpacks to properly reflect their contents.
Add a function for mapping from cirq objects to pygsti gate names.
Add a new class method that allows for instantiation of a pygsti circuit from a cirq one. Parsing the input and converting it layer-by-layer in pygsti format.
Add unit tests, one for conversion from cirq to pygsti, and another for conversion to openqasm.
Adds handling for implied idles and global idle specification when doing cirq to pygsti conversion. Also adds associated unit tests, and fixes a few aliasing problems with the cirq to pygsti name conversion.
Modifies the unitary_to_standard_gatename function to add the option for it to identify standard gate names for unitaries that match up to an overall global phase. Also can optionally return what that phase is if a match is found.
Add a fallback behavior which uses a new function for checking if a unitary corresponds to a built-in gate up to an overall phase to try and search for a matching gate if one is missing from the conversion dictionary. A warning is raised when this happens to alert the user.
Update the cirq integration demo notebook to include a demonstration of new cirq-to-pygsti conversion capabilities.
@coreyostrove coreyostrove added this to the 0.9.13 milestone Mar 19, 2024
@coreyostrove coreyostrove self-assigned this Mar 19, 2024
@coreyostrove coreyostrove requested a review from sserita March 19, 2024 21:28
@sserita sserita modified the milestones: 0.9.13, 0.9.12.2 Mar 26, 2024
Copy link
Contributor

@sserita sserita left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor discussion on default global idle behavior, otherwise close to merge!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for also including tutorial updates :)

std_unitaries['Gx'] = std_unitaries['Gxpi2']
std_unitaries['Gy'] = std_unitaries['Gypi2']
std_unitaries['Gz'] = std_unitaries['Gzpi2']

return std_unitaries


def unitary_to_standard_gatename(unitary):
def unitary_to_standard_gatename(unitary, up_to_phase = False, return_phase = False):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, we've had some confusion about the phase difference before. Great to make this explicit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the tests! :)

implied idles as part of a circuit layer containing
other explicitly specified gates.

global_idle : bool or string or Label, optional (default False)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A question/clarification on implicit vs global idle behavior. The default is False for both, but this results in Gi's being dropped for implicit idles everywhere EXCEPT for global idles - that is, in cell 17 of the example, we have Gi labels in partial idle layers, but the global idle layer does have Gis. I kinda expected no Gis anywhere in this case.

Maybe more succintly put, I expected the "True" behavior of global idle to be the default (i.e. cell 20), and to recover the current (i.e. cell 17) behavior, a user would have to explicitly put "Gi" for the global_idle string here. Another advantage of this approach is then the global_idle argument only takes one type of argument (a label-like one) rather than switching behavior on boolean/label-like arguments.

I am open to being convinced that current behavior is most desired though!

P.S. Another place where Jupytext examples/tutorials would probably make this discussion easier...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I was conflicted on the default behavior here. The original decision to make replacement of the global idle layers non-default is that unlike with implicit idles where the convention is pretty universally accepted (i.e. not including them), the convention for global idles is less so. I know we have Label(()), but I've always kind of disliked this convention (from a dev perspective it is kind of annoying and creates lots of edge cases to check for), so I initially wanted to force the choice of substitution to be an affirmative one. As you can see from the final implementation I eventually flip-flopped on this and did add a default label replacement choice of Label(()), so I think making this default would be alright. I'll probably change the names of these kwargs to be more descriptive while I'm at it.

Rename the kwargs for implied idle and global idle handling and change the default behavior of global idle handling to convert these by default. Updates the tutorial notebook and unit tests to reflect these changes.
@coreyostrove
Copy link
Contributor Author

Thanks for the feedback, @sserita. I have just pushed some updates which rename the kwargs of implied and global idle handling to remove_implied_idles and global_idle_replacement_label, respectively, which should hopefully be more self explanatory for end users. I have also changed the default behavior for the global idle (implied handling behavior is the same, but the default value is now instead True to match the renaming of the kwarg) so that they are replaced. Let me know if you have any other concerns.

Copy link
Contributor

@sserita sserita left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made a minor fix to the remove_implied_idles docstring, and think this is good to go as soon as the tests pass!

@sserita sserita merged commit 4d3a495 into develop Apr 2, 2024
4 checks passed
@sserita sserita deleted the feature-cirq-integration-updates branch April 2, 2024 22:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants