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

Adding CollectAndCollapse transpiler pass #8907

Merged
merged 43 commits into from
Nov 23, 2022

Conversation

alexanderivrii
Copy link
Member

@alexanderivrii alexanderivrii commented Oct 14, 2022

Summary

Note: CollapseChains has been renamed to CollectAndCollapse.

This is a shorter and a cleaner implementation of CollapseChains transpiler pass to collect and to consolidate blocks of gates, as described in the issue #5775 and temporarily implemented in #8319. Based on previous feedback, this pass is now completely general, allowing for arbitrary strategies to collect and to consolidate blocks in a circuit. To be completely general, the pass depends on two functions: the collection function and the collapsing function. The collection function collect_function takes a DAG and returns a list of blocks. The collapsing function collapse_function takes a DAG and a list of blocks, consolidates each block, and returns the modified DAG.

As two examples, the inherited CollectLinearFunctions collects blocks of CX and SWAP gates, and replaces each block with a LinearFunction, while the inherited class CollectCliffords collects blocks of "Clifford" gates and replaces each block with a Clifford.

This PR explicitly addresses collecting blocks of linear gates (the existing pass CollectLinearFunctions is reimplemented) and collecting blocks of Clifford gate (a new pass CollectCliffords is added). This does not include collecting blocks of commuting gates or heuristic depth optimization approach from #8319, these will be addressed in a different PR. This also does not address strategies such as Collect2qBlocks or CollectMultiQBlocks, which also can be added in the future.

To allow code reuse between the collection and collapsing functions of inherited classes, added a new class BlockCollector that examines the DAG and implements various collection strategies, and a new class BlockCollapser that implements various collapsing strategies. Currently BlockCollector includes the strategy to greedily collect all gates adhering to a given filter function (for example, collecting all Clifford gates), while BlockCollapser includes the strategy to consolidate all gates in a block to a single object (for example, a block of Clifford gates can be consolidated to a single Clifford).


The CollectAndCollapse supports the additional option do_commutative_analysisthat allows to exploit commutativity between gates in order to collect larger blocks of nodes. As an example, collecting blocks of CX gates in the following circuit:

qc = QuantumCircuit(2)
qc.cx(0, 1)
qc.z(0)
qc.cx(1, 0)

allows to consolidate the two CX gates, as the first CX gate and the Z-gate commute. Internally, setting do_commutative_analysis to True uses the DAGDependency representation of a DAG.

Both CollectLinearFunctions and CollectCliffords have additional options split_blocks and min_block_size.
The option split_blocks allows to split collected blocks into sub-blocks over disjoint subsets of qubits. As an example, in the following circuit:

qc = QuantumCircuit(4)
qc.cx(0, 2)
qc.cx(1, 3)
qc.cx(2, 0)
qc.cx(3, 1)
qc.cx(1, 3)

the single block of CX gates over qubits {0, 1, 2, 3} can be split into two disjoint sub-blocks, one over qubits {0, 2} and the other over qubits {1, 3}. The option min_block_size allows to specify the minimum size of the block to be consolidated,
blocks with fewer gates will not be modified. As an example, in the following circuit:

qc = QuantumCircuit(4)
qc.cx(1, 2)
qc.cx(2, 1)

the two CX gates will be consolidated when min_block_size is 1 or 2, and will remain unchanged when min_block_size is 3 or larger.

Details and comments

The CollectLinearFunctions transpiler pass was reimplemented and now inherits from CollectAndCollapse.

A new CollectCliffods transpiler pass (that collects blocks of Clifford gates and replaces each block by a Clifford) is added, also based on CollectAndCollapse.

The old functions collect_linear_blocks and split_blocks_into_components do not seem to be in Qiskit documentation, so they were removed without issuing deprecation warning.

The actual block collection code that supports both DAGCircuit and DAGDependency belongs to the class BlockCollector
(in dagcircuit/collect_blocks.py), and is a very slight generalization of the old code from CollectLinearFunctions.

The code for splitting a block of nodes in multiple sub-blocks over disjoint subsets of qubits belongs to the class BlockSplitter (in dagcircuit/collect_blocks.py). It also previously existed in CollectLinearFunctions, but is now reimplemented based on the Disjoint Set Union data structure (following ideas from CollectMultiQBlocks). The code for collapsing blocks of nodes belongs to the class BlockCollapser (also in dagcircuit/collect_blocks.py).

The DAGDependency has a function replace_block_with_op, which is adapted from DAGCircuit, see my comment about that in the code, but basically it is safe to replace a block of nodes in DAGDependency by a single node without breaking commutativity relations present in DAGDependency. The functions dagdependency_to_dag and dagdependency_to_circuit were slightly modified to traverse nodes in topological order, and one of the template matching tests needed a minor fix (it still returns the same dag up to some commuting gates swapped).

Tests to cover new options of CollectLinearFunctions and for collecting/consolidating Cliffords were added to test_linear_functions_passes.py and test_clifford_passes.py respectively.

@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:

@alexanderivrii
Copy link
Member Author

@ajavadia, you wanted to take a look at this when it's ready, so I am assigning this to you.

@alexanderivrii alexanderivrii added the mod: transpiler Issues and PRs related to Transpiler label Oct 14, 2022
@alexanderivrii alexanderivrii added this to the 0.23.0 milestone Oct 14, 2022
@coveralls
Copy link

coveralls commented Oct 14, 2022

Pull Request Test Coverage Report for Build 3535152082

  • 196 of 202 (97.03%) changed or added relevant lines in 10 files are covered.
  • 2 unchanged lines in 1 file lost coverage.
  • Overall coverage increased (+0.05%) to 84.534%

Changes Missing Coverage Covered Lines Changed/Added Lines %
qiskit/dagcircuit/collect_blocks.py 122 124 98.39%
qiskit/dagcircuit/dagdependency.py 19 23 82.61%
Files with Coverage Reduction New Missed Lines %
src/sabre_swap/layer.rs 2 98.95%
Totals Coverage Status
Change from base Build 3533913589: 0.05%
Covered Lines: 62879
Relevant Lines: 74383

💛 - Coveralls

@alexanderivrii alexanderivrii changed the title Adding CollapseChains transpiler pass Adding CollectAndCollapse transpiler pass Nov 6, 2022
@alexanderivrii alexanderivrii requested a review from kdk November 6, 2022 13:16
Copy link
Member

@kdk kdk 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 the updates @alexanderivrii , this looks great. One minor comment and then I think this is good to go.

@alexanderivrii alexanderivrii requested a review from kdk November 23, 2022 16:10
Copy link
Member

@kdk kdk 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 the updates, this LGTM.

@kdk kdk added the automerge label Nov 23, 2022
@kdk kdk added Changelog: New Feature Include in the "Added" section of the changelog Changelog: API Change Include in the "Changed" section of the changelog labels Nov 23, 2022
@mergify mergify bot merged commit 0fddf79 into Qiskit:main Nov 23, 2022
@alexanderivrii alexanderivrii deleted the block_collection branch November 24, 2022 06:59
Cryoris pushed a commit to Cryoris/qiskit-terra that referenced this pull request Jan 12, 2023
* Collecting and refining blocks of nodes from DAGCircuit and DAGDependency

* Fix to visualize Cliffords

* Changing method descriptions to refer to Operation instead of Instruction

* Adding replace_block_with_op method to DAGDependency

* Changing dagdependency_to_circuit and dag_dependency_to_dag to iterate over the nodes in topological order

* Tests for collecting blocks

* Adding CollapseChains base transpiler pass

* Reimplementing CollectLinearFunctions using CollapseChains

* Expanding tests for CollectLinearFunctions

* Add CollectCliffords transpiler pass and tests

* Adding new passes to __init__

* Adding release notes

* minor renaming

* pylint fix

* pylint fixes

* Fixing template matching test. By changing dagdependency_to_dag to use topological order, the constructed dag arranges gates in a slightly different order

* minor releasenotes fix

* docs fixes

* Generalizing CollapseChains to a very general collection and consolidation pass

* more reno polishing

* pylint

* Renaming create_op_node to _create_op_node

* adding clarification message

* release notes fix

* adding test as per review comments

* adding one more collection test

* adding tests with measure and conditional gates

* removing debug print function

* renaming

* Following the review comments, moving the arguments split_block and min_block_size to be a part of collection function

* improving docstrings

* Fixing/extending tests for collecting blocks (to account for new options), allowing to run multiple collections with different filter functions

* docstring fixes

* docstring fixes

* apply renaming from code review

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changelog: API Change Include in the "Changed" section of the changelog Changelog: New Feature Include in the "Added" section of the changelog mod: transpiler Issues and PRs related to Transpiler
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants