Reorder Pauli terms before Trotterization#12925
Conversation
Reordering the terms of a Pauli operator can reduce the depth of the evolution circuit if using the Lie-Trotter or Suzuki-Trotter methods. This commit adds a method `synthesis.evolution.product_formula.reorder_paulis` that does just that, based on a greedy graph coloring heuristic. This commit also adds the `reorder` option in the `ProductFormula`, `LieTrotter` and `SuzukiTrotter` constructors to allow for reordering before synthesis.
|
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 following people are relevant to this code:
|
Pull Request Test Coverage Report for Build 11729926405Details
💛 - Coveralls |
|
@altaris are you still pursuing this or do would you like us to help? 🙂 |
|
Sure! I'd love to see it through 💪
|
Before that, if reorder_paulis was given a single-term SparsePauliOp object, it would return it encapsulated in a list. Now, it returns it as is.
Cryoris
left a comment
There was a problem hiding this comment.
Overall the PR looks very nice! I left some comments below, in particular about the handling of lists of operators. Could you also add a release note describing the new argument? 🙂
mrossinek
left a comment
There was a problem hiding this comment.
Just adding my 2 cents here
If `reorder_paulis` is given a list of operators, then they are reordered and returned individually. Before this co mmit, they used to be added all together and then reordered, which always resulted in a single operator.
ShellyGarion
left a comment
There was a problem hiding this comment.
LGTM. thanks for the nice contribution to Qiskit. Some release notes are needed.
alexanderivrii
left a comment
There was a problem hiding this comment.
Thanks @Cryoris and the original contributor @altaris! I think allowing Pauli reordering is a useful option for the PauliEvolutionGate synthesis algorithms.
I have left a few minor comments and questions inline.
One more question: do you think that for Rustiq-based synthesis algorithm (and the plugin already accepts "preserve_order"), it might be beneficial to rearrange Paulis before passing the pauli network to Rustiq?
That is already possible to do with this PR, since the re-ordering happens before |
I think it makes sense to expose this to Rustiq plugin as well. And I think it makes sense to let Rustiq do the additional reordering. |
- add reno - docs - safer list concat
|
56e619c includes this option in the Rustiq plugin too 👍🏻 |
| | None | ||
| ) = None, | ||
| wrap: bool = False, | ||
| preserve_order: bool = False, |
There was a problem hiding this comment.
I thought the consensus here was to not reorder terms by default because of the potential performance overhead. Shouldn't the default be to True?
| | None | ||
| ) = None, | ||
| wrap: bool = False, | ||
| preserve_order: bool = False, |
There was a problem hiding this comment.
| preserve_order: bool = False, | |
| preserve_order: bool = True, |
| if "preserve_order" in options and isinstance(algo, ProductFormula): | ||
| algo.preserve_order = options["preserve_order"] | ||
|
|
There was a problem hiding this comment.
Thanks for adding this. A very small nitpick: we don't need another call to isinstance(also, ProductFormula) here, since we've just checked this on the line above.
|
I think given the open questions and the proximity to 1.3.0 (ie this is the last PR being tracked) it's probably better to defer this to 2.0.0 rather than force it in. This feature is a nice to have, but I don't think it's absolutely necessary for 1.3.0 |
|
Pushing to 2.0.0 after further discussion... |
alexanderivrii
left a comment
There was a problem hiding this comment.
Thanks @Cryoris. This PR very nicely concludes the work that was done to improve the support for Pauli evolutions: representing them as gates, improving expansion methods, adding the plugin interface, new synthesis algorithms and new options, porting relevant code to Rust.
mtreinish
left a comment
There was a problem hiding this comment.
I'm fine with merging this as is. I just have 2 small nits inline, but they can be fixed in a followup without issue and aren't worth blocking this over.
| preserve_order: If ``False``, allows reordering the terms of the operator to | ||
| potentially yield a shallower evolution circuit. Not relevant | ||
| when synthesizing operator with a single term. |
There was a problem hiding this comment.
I think from a docs perspective it would be good to explain the tradeoffs here, especially around runtime performance.
| terms = sorted(paulis, key=_term_sort_key) | ||
| graph = rx.PyGraph() | ||
| graph.add_nodes_from(terms) | ||
| indexed_nodes = list(enumerate(graph.nodes())) |
There was a problem hiding this comment.
I think you don't actually need to cast this is as a list, it should all work fine without it and save a copy.
Summary
Reordering the terms of a Pauli operator can reduce the depth of the evolution circuit if using the Lie-Trotter or Suzuki-Trotter methods. This PR adds the option to do just that.
Details and comments
This PR adds
synthesis.evolution.product_formula.reorder_paulisthat reorders Pauli terms based on a greedy graph coloring heuristic;reorderoption in theProductFormula,LieTrotterandSuzukiTrotterconstructors to allow for reordering before synthesis.