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 a default optimization level to generate_preset_pass_manager #12150

Merged
merged 14 commits into from
Jul 26, 2024

Conversation

mtreinish
Copy link
Member

Summary

This commit adds a default value to the generate_preset_pass_manager's optimization_level argument. If it's not specified optimization level 2 will be used. After #12148 optimization level 2 is a better fit for an optimal tradeoff between heuristic effort and runtime that makes it well suited as a default optimization level.

Details and comments

This commit adds a default value to the generate_preset_pass_manager's
optimization_level argument. If it's not specified optimization level 2
will be used. After Qiskit#12148 optimization level 2 is a better fit for an
optimal tradeoff between heuristic effort and runtime that makes it
well suited as a default optimization level.
@mtreinish mtreinish added Changelog: New Feature Include in the "Added" section of the changelog mod: transpiler Issues and PRs related to Transpiler labels Apr 5, 2024
@mtreinish mtreinish added this to the 1.1.0 milestone Apr 5, 2024
@mtreinish mtreinish requested a review from a team as a code owner April 5, 2024 21:57
@qiskit-bot
Copy link
Collaborator

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

  • @Qiskit/terra-core

@mtreinish mtreinish force-pushed the default-generate-preset-pass-manager branch from d263471 to 8191110 Compare April 5, 2024 22:02
@coveralls
Copy link

coveralls commented Apr 5, 2024

Pull Request Test Coverage Report for Build 10114185659

Details

  • 8 of 8 (100.0%) changed or added relevant lines in 2 files are covered.
  • 21 unchanged lines in 3 files lost coverage.
  • Overall coverage decreased (-0.02%) to 89.72%

Files with Coverage Reduction New Missed Lines %
qiskit/transpiler/passes/synthesis/unitary_synthesis.py 2 88.39%
crates/qasm2/src/lex.rs 7 91.35%
crates/qasm2/src/parse.rs 12 97.15%
Totals Coverage Status
Change from base Build 10111859581: -0.02%
Covered Lines: 66687
Relevant Lines: 74328

💛 - Coveralls

# Handle positional arguments for target and backend. This enables the usage
# pattern `generate_preset_pass_manager(backend.target)` to generate a default
# pass manager for a given target.
if isinstance(optimization_level, Target):
Copy link
Contributor

Choose a reason for hiding this comment

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

Personally, I'd rather this function not support any positional arguments.

I think we want a more ergonomic API on top of this function eventually anyways, e.g. #12161, so it seems too kludgy to me to try and make this accept a target positionally here.

Copy link
Member Author

Choose a reason for hiding this comment

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

#12161 is actually what I'm not sure we want to do. Adding a 3rd API with different semantics to do what we already have two interfaces for seems like a mistake to me. If people really want a different name I feel like we really should just alias it (but I still don't think it's worth it). But adding yet another entrypoint to accomplish the same thing feels like a mistake. If people are complaining about the ergonomics of the existing interface I feel like we should just evolve it in-place instead of diverging it again and requiring people to learn yet another thing.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, it's unfortunate that we've ended up here, but I think the right thing to do for users is to make it so the common patterns {transpile,generate_preset_pass_manager}({backend,target}, optimization_level=2) work the same in both forms. It ends up in an ugly signature for us, but we can tidy that up in place and potentially fix the signature properly for Qiskit 2.0+.

@jakelishman jakelishman self-assigned this Apr 18, 2024
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.

This looks fine in principle to me, I'm just concerned about how we're setting this to have a different default optimisation level to transpile. We already get complaints whenever the interfaces of transpile and this diverge around type inference / whatever, and I guess I'd roughly rather we moved the two in step?

I can live with the split if it was already discussed more in the team, though.

# Handle positional arguments for target and backend. This enables the usage
# pattern `generate_preset_pass_manager(backend.target)` to generate a default
# pass manager for a given target.
if isinstance(optimization_level, Target):
Copy link
Member

Choose a reason for hiding this comment

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

Yeah, it's unfortunate that we've ended up here, but I think the right thing to do for users is to make it so the common patterns {transpile,generate_preset_pass_manager}({backend,target}, optimization_level=2) work the same in both forms. It ends up in an ugly signature for us, but we can tidy that up in place and potentially fix the signature properly for Qiskit 2.0+.

This commit updates the transpile() function's optimization_level argument
default value to match generate_preset_pass_manager's new default to use 2
instead of 1. This is arguably a breaking API change, but since the
semantics are equivalent with two minor edge cases with implicit behavior
that were a side effect of the level 1 preset pass manager's construction
(which are documented in the release notes) we're ok making it in this
case. Some tests which we're relying on the implicit behavior of
optimization level 1 are updated to explicitly set the optimization
level argument which will retain this behavior.
@mtreinish mtreinish requested review from a team, eggerdj, wshanks and jyu00 as code owners April 30, 2024 23:41
@mtreinish
Copy link
Member Author

This looks fine in principle to me, I'm just concerned about how we're setting this to have a different default optimisation level to transpile. We already get complaints whenever the interfaces of transpile and this diverge around type inference / whatever, and I guess I'd roughly rather we moved the two in step?

I can live with the split if it was already discussed more in the team, though.

I updated the transpile() default to level 2 to match in: 34e9ee4 I'm a bit worried this is a breaking api change though. While at a high level the semantics are equivalent as the transpile function compiles the circuit in the same way. There were some implicit behaviors that came with level 1 which don't work in higher optimization levels. The two cases I know about are the implicit trivial layout if it's perfect and working with discrete basis sets. The unit tests flagged these as they were relying on this behavior, I updated those tests to explicitly use level 1 in those cases. I've also documented these edge cases in the release notes. It's arguable whether that's is part of our API contract though, because neither are actually defined behavior, more just implicit expectations/assumptions. However, level 1 being the default was explicitly documented...

@mtreinish
Copy link
Member Author

I'm thinking that if we want to do this for 1.1.0 we should drop 34e9ee4 and save that for 1.2. There seem to be a lot of issues with using level2 as the default in testing. There might be some more implicit assumptions I didn't think of that the tests are flagging. FWIW, every commit I've pushed up I ran the tests locally with and everything passed I assume it's either the presence of optional dependencies or py3.8 vs 3.12 that's causing the failures. But it's making me uneasy about making a potentially breaking change at the last minute before a release.

@jakelishman
Copy link
Member

jakelishman commented May 2, 2024

An alternative to moving transpile's default in this PR is to set the default for generate_preset_pass_manager to O1, and then move them both to O2 for Qiskit 2.0? Totally agree that it feels too big a step to move transpile's default at this point in time.

I'd like to see them stay in step at all times, but I can live with it if the decision is to go with O2 for this and move transpile to match it later.

@mtreinish mtreinish modified the milestones: 1.1.0, 1.2.0 May 2, 2024
@ElePT ElePT self-assigned this Jul 19, 2024
Copy link
Contributor

@ElePT ElePT left a comment

Choose a reason for hiding this comment

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

The PR looks good to me, I went in and fixed a couple of missing tests that were optimization-level dependant, or were using the full pipeline to only test the effect of a single transpiler pass (and that made them optimization-level dependant). Before approving, I want to confirm that we want to move on with the optimization level 2 default in both transpile and generate_ppm (I am going to call it like this from now on) for 1.2. Thoughts? @jakelishman @mtreinish @1ucian0

@ElePT ElePT force-pushed the default-generate-preset-pass-manager branch from d935ae9 to 3e987cd Compare July 24, 2024 15:32
@ElePT ElePT force-pushed the default-generate-preset-pass-manager branch from 3e987cd to 479ac9f Compare July 24, 2024 15:39
@mtreinish
Copy link
Member Author

mtreinish commented Jul 24, 2024

I'm good with doing this for 1.2, if there are no objections from anyone else. I'm personally still a bit apprehensive about the API implications on changing transpile() because of the test changes we needed to make and I'm concerned those are implicit user expectations even if they're not explicitly documented around the behavior of transpile(qc, backend). But I'm willing to fall back on the statement that our stability contract is to our documented interfaces, and these underlying assumptions aren't documented as part of transpile(). Then this can be viewed as being no different than changing an optimization pass to be do more work in the preset pass managers.

I will push up a small tweak to the upgrade release note though to elaborate a bit more on the benefits of the change to transpile() since I just realized it's never mentioned.

Copy link
Contributor

@ElePT ElePT left a comment

Choose a reason for hiding this comment

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

I left a few suggestions for the reno.

Copy link
Contributor

@ElePT ElePT left a comment

Choose a reason for hiding this comment

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

I commited the reno suggestions and will approve the PR, @mtreinish, feel free to add it to the merge queue if you agree with the changes or modify them if you don't.

@mtreinish mtreinish enabled auto-merge July 26, 2024 17:27
@mtreinish mtreinish added this pull request to the merge queue Jul 26, 2024
Merged via the queue into Qiskit:main with commit c8c53cc Jul 26, 2024
15 checks passed
Procatv pushed a commit to Procatv/qiskit-terra-catherines that referenced this pull request Aug 1, 2024
…kit#12150)

* Add a default optimization level to generate_preset_pass_manager

This commit adds a default value to the generate_preset_pass_manager's
optimization_level argument. If it's not specified optimization level 2
will be used. After Qiskit#12148 optimization level 2 is a better fit for an
optimal tradeoff between heuristic effort and runtime that makes it
well suited as a default optimization level.

* Update transpile()'s default opt level to match

This commit updates the transpile() function's optimization_level argument
default value to match generate_preset_pass_manager's new default to use 2
instead of 1. This is arguably a breaking API change, but since the
semantics are equivalent with two minor edge cases with implicit behavior
that were a side effect of the level 1 preset pass manager's construction
(which are documented in the release notes) we're ok making it in this
case. Some tests which we're relying on the implicit behavior of
optimization level 1 are updated to explicitly set the optimization
level argument which will retain this behavior.

* Update more tests expecting optimization level 1

* * Set optimization level to 1 in test_approximation_degree.

* Replace use of transpile with specific pass in  HLS tests.

* Set optimization_level=1 in layout-dependent tests.

* Expand upgrade note explanation on benefits of level 2

* Apply Elena's reno suggestions

---------

Co-authored-by: Elena Peña Tapia <epenatap@gmail.com>
Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>
@mtreinish mtreinish deleted the default-generate-preset-pass-manager branch August 6, 2024 19:41
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
Status: done
Development

Successfully merging this pull request may close these issues.

6 participants