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

Make heuristic score sorting robust in 1q optimization pass #9239

Closed
wants to merge 1 commit into from

Conversation

mtreinish
Copy link
Member

Summary

In #8197 the Optimize1qGatesDecomposition was updated to be target aware and as part of that a new heuristic scoring was added to determine which decomposition was the best performing and should be used. However, in the case of an error rate of 0.0 the desired behavior was to pick the decomposition which was shortest. In #8197 this was accomplished by just doing -100 + len(decomposition) which worked in the general case as long as the gate counts are < 100 (which in practice will always be the case). For robustness this changes the return for the scoring function to be (error_rate, sequence_length) to give us the sorting without changing the measured error rate.

Details and comments

In Qiskit#8197 the Optimize1qGatesDecomposition was updated to be target aware
and as part of that a new heuristic scoring was added to determine which
decomposition was the best performing and should be used. However, in
the case of an error rate of 0.0 the desired behavior was to pick the
decomposition which was shortest. In Qiskit#8197 this was accomplished by just
doing `-100 + len(decomposition)` which worked in the general case as
long as the gate counts are < 100 (which in practice will always be the
case). For robustness this changes the return for the scoring function
to be `(error_rate, sequence_length)` to give us the sorting without
changing the measured error rate.
@mtreinish mtreinish added the Changelog: None Do not include in changelog label Dec 2, 2022
@mtreinish mtreinish added this to the 0.23.0 milestone Dec 2, 2022
@mtreinish mtreinish requested a review from a team as a code owner December 2, 2022 21:41
@qiskit-bot
Copy link
Collaborator

Thank you for opening a new pull request.

Before your PR can be merged it will first need to pass continuous integration tests and be reviewed. Sometimes the review process can be slow, so please be patient.

While you're waiting, please feel free to review other open PRs. While only a subset of people are authorized to approve pull requests for merging, everyone is encouraged to review open pull requests. Doing reviews helps reduce the burden on the core team and helps make the project's code better for everyone.

One or more of the the following people are requested to review this:

  • @Qiskit/terra-core

@coveralls
Copy link

Pull Request Test Coverage Report for Build 3605288117

  • 5 of 5 (100.0%) changed or added relevant lines in 1 file are covered.
  • 3 unchanged lines in 1 file lost coverage.
  • Overall coverage increased (+0.04%) to 84.595%

Files with Coverage Reduction New Missed Lines %
src/sabre_swap/layer.rs 3 98.43%
Totals Coverage Status
Change from base Build 3604374696: 0.04%
Covered Lines: 63145
Relevant Lines: 74644

💛 - Coveralls

Comment on lines +115 to +119
new_error = _error(new_circ, self._target, qubit)
if isinstance(new_error, tuple):
error_rate = new_error[0]
else:
error_rate = new_error
Copy link
Member

Choose a reason for hiding this comment

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

If target is None, the output of _error is the length of the circuit, which isn't really an error rate. Is that what you meant to happen? If so, we could change the function to just return (len(circuit),) instead to simplify some checking.

Comment on lines -121 to +126
or np.isclose(_error(new_circ, self._target, qubit), 0)
or np.isclose(error_rate, 0)
Copy link
Member

Choose a reason for hiding this comment

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

This check feels weird, because before this PR the last line could only have triggered if the error rate was "close to" 0, but not actually 0 - in that case, it would have been replaced by -100 + len(circuit), so not be close any more. I'm not sure if that was intended - the behaviour it'll have after this PR (anything "close to" zero triggers the replacement) feels more natural to me.

@@ -112,13 +112,18 @@ def _substitution_checks(self, dag, old_run, new_circ, basis, qubit):
# if we're outside of the basis set, we're obligated to logically decompose.
# if we're outside of the set of gates for which we have physical definitions,
# then we _try_ to decompose, using the results if we see improvement.
new_error = _error(new_circ, self._target, qubit)
Copy link
Contributor

@kevinhartman kevinhartman Dec 2, 2022

Choose a reason for hiding this comment

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

Not sure if it's overkill, but I think it might be cleaner and less error-prone to add a local class to encapsulate the error tuple, and then generate a total ordering for it with @functools.total_ordering.

It looks like _error is used by _resynthesize_run as a key to min soI'd worry there might be times where code accidentally compares tuples to numbers.

EDIT: crossed-out isn't relevant (didn't notice at first glance that the target is bound as the same for all).

Copy link
Member

Choose a reason for hiding this comment

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

Tuple[T, ...] has an automatic total ordering in Python if type T has a total ordering itself, regardless of whether the lengths match - using tuples in comparisons is fairly idiomatic (e.g. if sys.version_info < (3, 10) etc). Maybe I'm misunderstanding what you meant, though.

@mtreinish mtreinish removed this from the 0.23.0 milestone Jan 17, 2023
@mtreinish
Copy link
Member Author

I baked this into a larger refactor of this pass in #9578 so we can close this PR as it's not needed anymore.

@mtreinish mtreinish closed this Feb 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changelog: None Do not include in changelog
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants