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 MinimumPoint transpiler pass #9612

Merged
merged 8 commits into from
Mar 30, 2023
Merged

Conversation

mtreinish
Copy link
Member

@mtreinish mtreinish commented Feb 17, 2023

Summary

This commit adds a new transpiler pass MinimumPoint which is used to find a local minimum point from the property set between executions of the pass. This is similar to the existing FixedPoint pass but will find the minimum fixed point over the past n exeuctions as opposed to finding a when two subsequent exectuions are at the same point. This is then used in optimization level 3 because the 2q unitary synthesis optimization that is part of the optimization loop can occasionally get stuck oscillating between multiple different equivalent decompositions which prevents the fixed point condition from ever being reached. By checking that we've reached the minimum over the last 5 executions we ensure we're reaching an exit condition in this situation.

Details and comments

Fixes #5832
Fixes #9177
Fixes #9776

(the underlying cause of the optimization loop's inability to converge at optimization level 3 is not fixed here, there is still a root cause of instability in UnitarySynthesis this just changes the loop exit condition so we're never stuck in an infinte loop)

@mtreinish mtreinish added Changelog: New Feature Include in the "Added" section of the changelog mod: transpiler Issues and PRs related to Transpiler labels Feb 17, 2023
@mtreinish mtreinish added this to the 0.24.0 milestone Feb 17, 2023
@mtreinish mtreinish requested a review from a team as a code owner February 17, 2023 17:38
@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

coveralls commented Feb 17, 2023

Pull Request Test Coverage Report for Build 4565674227

  • 45 of 45 (100.0%) changed or added relevant lines in 4 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-0.01%) to 85.367%

Totals Coverage Status
Change from base Build 4564463001: -0.01%
Covered Lines: 67151
Relevant Lines: 78662

💛 - Coveralls

@1ucian0 1ucian0 self-assigned this Feb 22, 2023
Comment on lines 42 to 51
* ``{prefix}_minimum_point_count`` - Used to track the number of executions since
the current minimum was found
* ``{prefix}_backtrack_history`` - Stores the current minimum value and :class:`~.DAGCircuit`
* ``{prefix}_minimum_point`` - This value gets set to ``True`` when either a fixed point
is reached over the ``backtrack_depth`` executions, or ``backtrack_depth`` was exceeded
and an earlier minimum is restored.
"""
Copy link
Member

Choose a reason for hiding this comment

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

This bullet list seems to not render correctly:

Screenshot 2023-03-11 at 15 08 21

Copy link
Member

Choose a reason for hiding this comment

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

there's an extra space in the indentation, which is causing it to be parsed as a bullet point containing a single-item definition list

Copy link
Member

@jakelishman jakelishman left a comment

Choose a reason for hiding this comment

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

I'm happy with the logic of what this PR is trying to accomplish, and I'm happy that it'll be superior to what we've got in place already, although maybe we should replace all use of FixedPoint with this - it feels like an accident waiting to happen in other places too. My issues are mostly just with legibility - the logic is quite tricksy, so I think it's important that we put a good amount of effort into making both it and its tests as readable as possible.

qiskit/transpiler/passes/utils/minimum_point.py Outdated Show resolved Hide resolved
test/python/compiler/test_transpiler.py Show resolved Hide resolved
Comment on lines 108 to 179
def test_min_reset_backtrack_range(self):
"""Test minimum resets backtrack depth."""
min_pass = MinimumPoint(["fidelity", "depth", "size"], prefix="test")
dag = DAGCircuit()
min_pass.property_set["fidelity"] = 0.875
min_pass.property_set["depth"] = 15
min_pass.property_set["size"] = 20
min_pass.run(dag)
self.assertEqual(min_pass.property_set["test_minimum_point_count"], 1)
self.assertIsNone(min_pass.property_set["test_backtrack_history"])
self.assertIsNone(min_pass.property_set["test_min_point"])
Copy link
Member

Choose a reason for hiding this comment

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

Some of the assertions in these tests feel rather like testing relatively minor implementation details, like the exact objects we expect are tracked with very specific names in the property set.

Leaving that aside, though, the test is quite hard to quickly check what the sequence of values are being set as the properties; for something like this, I think it's maybe easier if we could define the sequence of inserted values and expected values up in single lists at the top of the test so all the context is localised, then loop through them.

Copy link
Member Author

Choose a reason for hiding this comment

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

I left the tests mostly in place like this primarily to make it explicit what is happening in each iteration. I worry the details of the exact logic flow would be lost with a for loop. Especially given the complexity of the logic going on here my thinking was it might be difficult to track and testing it explicitly like this made it easier for me to ensure I got the expected logic. I agree that it does end up being a bit repetitive and a bit too detailed. In e2c8cd0 I added a bunch of comments to each iteration to explain the context.

This commit adds a new transpiler pass MinimumPoint which is used to
find a local minimum point from the property set between executions of
the pass. This is similar to the existing FixedPoint pass but will find
the minimum fixed point over the past n exeuctions as opposed to finding
a when two subsequent exectuions are at the same point. This is then
used in optimization level 3 because the 2q unitary synthesis
optimization that is part of the optimization loop can occasionally get
stuck oscillating between multiple different equivalent decompositions
which prevents the fixed point condition from ever being reached. By
checking that we've reached the minimum over the last 5 executions we
ensure we're reaching an exit condition in this situation.

Fixes Qiskit#5832
Fixes Qiskit#9177

(the underlying cause of the optimization loop's inability to converge
at optimization level 3 is not fixed here, there is still a root cause
of instability in UnitarySynthesis this just changes the loop exit
condition so we're never stuck in an infinte loop)
This commit reworks the logic of the pass to track the state via a
dataclass instead of using separate property set fields. This cleans up
the code for dealing with checking the current state relative to earlier
iterations by making the access just attributes instead of secret
strings. At the same time the tests were updated to handle this new data
structure comments were added to better explain the logic flow being
tested.
Copy link
Member

@jakelishman jakelishman left a comment

Choose a reason for hiding this comment

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

The slots thing is Python 3.10+ only, but with that and the minor grammar tweaks in the comments for better legibility, this looks good to me. The comments help a lot, and I think you're probably right about not wanting to do things in a loop in the tests.

qiskit/transpiler/passes/utils/minimum_point.py Outdated Show resolved Hide resolved
qiskit/transpiler/passes/utils/minimum_point.py Outdated Show resolved Hide resolved
qiskit/transpiler/passes/utils/minimum_point.py Outdated Show resolved Hide resolved
qiskit/transpiler/passes/utils/minimum_point.py Outdated Show resolved Hide resolved
qiskit/transpiler/passes/utils/minimum_point.py Outdated Show resolved Hide resolved
test/python/transpiler/test_minimum_point.py Outdated Show resolved Hide resolved
Copy link
Member

@jakelishman jakelishman left a comment

Choose a reason for hiding this comment

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

Ace, thanks!

@jakelishman jakelishman added this pull request to the merge queue Mar 30, 2023
Merged via the queue into Qiskit:main with commit 694ade4 Mar 30, 2023
ElePT pushed a commit to ElePT/qiskit that referenced this pull request Apr 5, 2023
* Add MinimumPoint transpiler pass

This commit adds a new transpiler pass MinimumPoint which is used to
find a local minimum point from the property set between executions of
the pass. This is similar to the existing FixedPoint pass but will find
the minimum fixed point over the past n exeuctions as opposed to finding
a when two subsequent exectuions are at the same point. This is then
used in optimization level 3 because the 2q unitary synthesis
optimization that is part of the optimization loop can occasionally get
stuck oscillating between multiple different equivalent decompositions
which prevents the fixed point condition from ever being reached. By
checking that we've reached the minimum over the last 5 executions we
ensure we're reaching an exit condition in this situation.

Fixes Qiskit#5832
Fixes Qiskit#9177

(the underlying cause of the optimization loop's inability to converge
at optimization level 3 is not fixed here, there is still a root cause
of instability in UnitarySynthesis this just changes the loop exit
condition so we're never stuck in an infinte loop)

* Doc copy-paste error cleanups

* Rework logic to track state with a dataclass

This commit reworks the logic of the pass to track the state via a
dataclass instead of using separate property set fields. This cleans up
the code for dealing with checking the current state relative to earlier
iterations by making the access just attributes instead of secret
strings. At the same time the tests were updated to handle this new data
structure comments were added to better explain the logic flow being
tested.

* Fix doc typo

* Apply suggestions from code review

Co-authored-by: Jake Lishman <[email protected]>

* Update slots syntax for dataclass to be compatible with Python < 3.10

* Update property set check in tests

---------

Co-authored-by: Jake Lishman <[email protected]>
giacomoRanieri pushed a commit to giacomoRanieri/qiskit-terra that referenced this pull request Apr 16, 2023
* Add MinimumPoint transpiler pass

This commit adds a new transpiler pass MinimumPoint which is used to
find a local minimum point from the property set between executions of
the pass. This is similar to the existing FixedPoint pass but will find
the minimum fixed point over the past n exeuctions as opposed to finding
a when two subsequent exectuions are at the same point. This is then
used in optimization level 3 because the 2q unitary synthesis
optimization that is part of the optimization loop can occasionally get
stuck oscillating between multiple different equivalent decompositions
which prevents the fixed point condition from ever being reached. By
checking that we've reached the minimum over the last 5 executions we
ensure we're reaching an exit condition in this situation.

Fixes Qiskit#5832
Fixes Qiskit#9177

(the underlying cause of the optimization loop's inability to converge
at optimization level 3 is not fixed here, there is still a root cause
of instability in UnitarySynthesis this just changes the loop exit
condition so we're never stuck in an infinte loop)

* Doc copy-paste error cleanups

* Rework logic to track state with a dataclass

This commit reworks the logic of the pass to track the state via a
dataclass instead of using separate property set fields. This cleans up
the code for dealing with checking the current state relative to earlier
iterations by making the access just attributes instead of secret
strings. At the same time the tests were updated to handle this new data
structure comments were added to better explain the logic flow being
tested.

* Fix doc typo

* Apply suggestions from code review

Co-authored-by: Jake Lishman <[email protected]>

* Update slots syntax for dataclass to be compatible with Python < 3.10

* Update property set check in tests

---------

Co-authored-by: Jake Lishman <[email protected]>
king-p3nguin pushed a commit to king-p3nguin/qiskit-terra that referenced this pull request May 22, 2023
* Add MinimumPoint transpiler pass

This commit adds a new transpiler pass MinimumPoint which is used to
find a local minimum point from the property set between executions of
the pass. This is similar to the existing FixedPoint pass but will find
the minimum fixed point over the past n exeuctions as opposed to finding
a when two subsequent exectuions are at the same point. This is then
used in optimization level 3 because the 2q unitary synthesis
optimization that is part of the optimization loop can occasionally get
stuck oscillating between multiple different equivalent decompositions
which prevents the fixed point condition from ever being reached. By
checking that we've reached the minimum over the last 5 executions we
ensure we're reaching an exit condition in this situation.

Fixes Qiskit#5832
Fixes Qiskit#9177

(the underlying cause of the optimization loop's inability to converge
at optimization level 3 is not fixed here, there is still a root cause
of instability in UnitarySynthesis this just changes the loop exit
condition so we're never stuck in an infinte loop)

* Doc copy-paste error cleanups

* Rework logic to track state with a dataclass

This commit reworks the logic of the pass to track the state via a
dataclass instead of using separate property set fields. This cleans up
the code for dealing with checking the current state relative to earlier
iterations by making the access just attributes instead of secret
strings. At the same time the tests were updated to handle this new data
structure comments were added to better explain the logic flow being
tested.

* Fix doc typo

* Apply suggestions from code review

Co-authored-by: Jake Lishman <[email protected]>

* Update slots syntax for dataclass to be compatible with Python < 3.10

* Update property set check in tests

---------

Co-authored-by: Jake Lishman <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changelog: New Feature Include in the "Added" section of the changelog mod: transpiler Issues and PRs related to Transpiler
Projects
None yet
5 participants