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

Add inverse function to Operation in rust #13168

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

ShellyGarion
Copy link
Member

Summary

Close #13157

Details and comments

@ShellyGarion ShellyGarion added the Rust This PR or issue is related to Rust code in the repository label Sep 17, 2024
@ShellyGarion ShellyGarion added this to the 1.3.0 milestone Sep 17, 2024
@ShellyGarion ShellyGarion requested a review from a team as a code owner September 17, 2024 14:08
@qiskit-bot
Copy link
Collaborator

One or more of the following people are relevant to this code:

  • @Qiskit/terra-core
  • @kevinhartman
  • @mtreinish

@ShellyGarion
Copy link
Member Author

ShellyGarion commented Sep 18, 2024

The following gates do not have an inverse which is a StandardGate:

  • DCXGate
  • ISwapGate
  • CSXGate
  • RCCXGate
  • C3SXGate
  • RC3XGate

@coveralls
Copy link

coveralls commented Sep 18, 2024

Pull Request Test Coverage Report for Build 10922800047

Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

Details

  • 151 of 184 (82.07%) changed or added relevant lines in 2 files are covered.
  • 393 unchanged lines in 5 files lost coverage.
  • Overall coverage decreased (-0.1%) to 88.808%

Changes Missing Coverage Covered Lines Changed/Added Lines %
crates/circuit/src/packed_instruction.rs 0 3 0.0%
crates/circuit/src/operations.rs 151 181 83.43%
Files with Coverage Reduction New Missed Lines %
qiskit/transpiler/passes/synthesis/unitary_synthesis.py 2 88.26%
crates/qasm2/src/lex.rs 5 91.73%
qiskit/qasm2/parse.py 6 96.7%
qiskit/synthesis/two_qubit/xx_decompose/decomposer.py 6 90.91%
crates/circuit/src/dag_circuit.rs 374 87.05%
Totals Coverage Status
Change from base Build 10892476121: -0.1%
Covered Lines: 73629
Relevant Lines: 82908

💛 - Coveralls

@ShellyGarion ShellyGarion changed the title [WIP] Add inverse function to Operation in rust Add inverse function to Operation in rust Sep 18, 2024
Copy link
Member

@mtreinish mtreinish left a comment

Choose a reason for hiding this comment

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

Thanks for getting this started it looking good. I have a couple of inline comments and questions to start.

Comment on lines +2498 to +2500
fn inverse(&self, _params: &[Param]) -> Option<(StandardGate, Vec<Param>)> {
None
}
Copy link
Member

Choose a reason for hiding this comment

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

Is there ever a case where a Python Operation will have an inverse defined? I know it's not part of the abstract interface, but I'm wondering if we should try and fallback to None? @alexanderivrii maybe you have some thoughts here?

@@ -2043,6 +2057,155 @@ impl Operation for StandardGate {
fn standard_gate(&self) -> Option<StandardGate> {
Some(*self)
}
fn inverse(&self, params: &[Param]) -> Option<(StandardGate, Vec<Param>)> {
Copy link
Member

Choose a reason for hiding this comment

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

Everywhere else we work with parameters in Rust we tend to use SmallVec<[Param; 3]> to keep things on the stack unless there are more than 3 elements. It might be worth changing this and updating the vec! macro usage to smallvec!.

@@ -167,6 +167,7 @@ pub trait Operation {
fn definition(&self, params: &[Param]) -> Option<CircuitData>;
fn standard_gate(&self) -> Option<StandardGate>;
fn directive(&self) -> bool;
fn inverse(&self, params: &[Param]) -> Option<(StandardGate, Vec<Param>)>;
Copy link
Member

Choose a reason for hiding this comment

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

Does this work in the case of PyGate? I don't think there is a guarantee that a Python defined gate's inverse will be a StandardGate. I actually think it is pretty unlikely in practice, since if a custom gate were expressible as the inverse of a StandardGate it'd probably just be a StandardGate. I think you can just do:

Suggested change
fn inverse(&self, params: &[Param]) -> Option<(StandardGate, Vec<Param>)>;
fn inverse(&self, params: &[Param]) -> Option<(Self, Vec<Param>)>;

then for impl Operation for StandardGate .inverse() returns a StandardGate and for impl Operator for PyGate .inverse() returns a PyGate.

Self::C3SXGate => None, // the inverse in not a StandardGate
Self::RC3XGate => None, // the inverse in not a StandardGate
}
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Did you want to add a rust space test asserting that all the StandardGates multiplied with their inverse were the identity? It would be good to get in the practice of having more rust space tests, but since we have coverage from python I don't think it's strictly necessary.

@kevinhartman has been working on demonstrating a pattern of using the py token from rust space tests: #13169 (since we still need it for multiply_param even if there isn't a parameter expression).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Rust This PR or issue is related to Rust code in the repository
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add inverse function to Opearion in rust
4 participants