Skip to content

Update synth_mcx_kg24 to use relative phase Toffolis #14394

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

Merged
merged 12 commits into from
May 30, 2025

Conversation

patelvyom
Copy link
Contributor

Summary

This PR enhances the recently introduced MCX synthesis methods (see #13922) by replacing standard Toffoli gates with relative-phase Toffolis, resulting in significantly improved CX gate counts.

Details and Comments

By leveraging relative-phase Toffolis, this PR reduces CX counts by up to a factor of 2 across several synthesis strategies. Notably, the CX counts for the following methods now match!

  • synth_mcx_2_clean_kg24
  • synth_mcx_1_clean_kg24
  • synth_mcx_n_clean_m15

Key improvements:

  • Replace cascades of CCX + X with _n_parallel_ccx_x, using relative-phase Toffolis internally.
  • Use relative-phase Toffolis in ancilla initialization to generate conditionally clean ancillae more efficiently.
  • Update the HLS transpiler plugin to reflect the new MCX decomposition order.
  • Adjust CX count unit tests to match the new lower bounds enabled by this optimization.

Tagging @ShellyGarion, as you're familiar with the recent changes in this area.

@patelvyom patelvyom requested a review from a team as a code owner May 17, 2025 04:03
@qiskit-bot qiskit-bot added the Community PR PRs from contributors that are not 'members' of the Qiskit repo label May 17, 2025
@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 following people are relevant to this code:

  • @Qiskit/terra-core

@patelvyom
Copy link
Contributor Author

Some benchmarks to justify the change in HLS transpiler:

CX Counts

+-----+----------------+----------------+---------------+---------------+----------------+----------------+---------------+
|   n |   2_clean_kg24 |   1_clean_kg24 |   n_clean_m15 |   n_dirty_i15 |   2_dirty_kg24 |   1_dirty_kg24 |   1_clean_b95 |
|-----+----------------+----------------+---------------+---------------+----------------+----------------+---------------|
|   3 |             12 |             12 |            12 |            14 |             18 |             18 |            14 |
|   4 |             18 |             18 |            18 |            26 |             30 |             30 |            36 |
|   5 |             24 |             24 |            24 |            34 |             42 |             42 |            48 |
|   6 |             30 |             30 |            30 |            42 |             54 |             54 |            64 |
|   7 |             36 |             36 |            36 |            50 |             66 |             66 |            88 |
|   8 |             42 |             42 |            42 |            58 |             78 |             78 |           104 |
|   9 |             48 |             48 |            48 |            66 |             90 |             90 |           120 |
|  10 |             54 |             54 |            54 |            74 |            102 |            102 |           136 |
|  11 |             60 |             60 |            60 |            82 |            114 |            114 |           152 |
|  12 |             66 |             66 |            66 |            90 |            126 |            126 |           168 |
|  13 |             72 |             72 |            72 |            98 |            138 |            138 |           184 |
|  14 |             78 |             78 |            78 |           106 |            150 |            150 |           200 |
|  15 |             84 |             84 |            84 |           114 |            162 |            162 |           216 |
|  16 |             90 |             90 |            90 |           122 |            174 |            174 |           232 |
|  17 |             96 |             96 |            96 |           130 |            186 |            186 |           248 |
|  18 |            102 |            102 |           102 |           138 |            198 |            198 |           264 |
|  19 |            108 |            108 |           108 |           146 |            210 |            210 |           280 |
|  20 |            114 |            114 |           114 |           154 |            222 |            222 |           296 |
|  21 |            120 |            120 |           120 |           162 |            234 |            234 |           312 |
|  22 |            126 |            126 |           126 |           170 |            246 |            246 |           328 |
|  23 |            132 |            132 |           132 |           178 |            258 |            258 |           344 |
|  24 |            138 |            138 |           138 |           186 |            270 |            270 |           360 |
+-----+----------------+----------------+---------------+---------------+----------------+----------------+---------------+

Depth

+-----+----------------+----------------+---------------+---------------+----------------+----------------+---------------+
|   n |   2_clean_kg24 |   1_clean_kg24 |   n_clean_m15 |   n_dirty_i15 |   2_dirty_kg24 |   1_dirty_kg24 |   1_clean_b95 |
|-----+----------------+----------------+---------------+---------------+----------------+----------------+---------------|
|   3 |             22 |             22 |            24 |            27 |             30 |             30 |            27 |
|   4 |             32 |             32 |            36 |            51 |             53 |             53 |            65 |
|   5 |             44 |             40 |            48 |            67 |             77 |             69 |            87 |
|   6 |             50 |             52 |            60 |            83 |             89 |             93 |           116 |
|   7 |             50 |             60 |            72 |            99 |             89 |            109 |           154 |
|   8 |             52 |             72 |            84 |           115 |             93 |            133 |           188 |
|   9 |             56 |             80 |            96 |           131 |            101 |            149 |           222 |
|  10 |             64 |             92 |           108 |           147 |            117 |            173 |           254 |
|  11 |             76 |            100 |           120 |           163 |            141 |            189 |           286 |
|  12 |             76 |            112 |           132 |           179 |            141 |            213 |           318 |
|  13 |             76 |            120 |           144 |           195 |            141 |            229 |           350 |
|  14 |             76 |            132 |           156 |           211 |            141 |            253 |           382 |
|  15 |             80 |            140 |           168 |           227 |            149 |            269 |           414 |
|  16 |             84 |            152 |           180 |           243 |            157 |            293 |           446 |
|  17 |             84 |            160 |           192 |           259 |            157 |            309 |           478 |
|  18 |             88 |            172 |           204 |           275 |            165 |            333 |           510 |
|  19 |             96 |            180 |           216 |           291 |            181 |            349 |           542 |
|  20 |            104 |            192 |           228 |           307 |            197 |            373 |           574 |
|  21 |            104 |            200 |           240 |           323 |            197 |            389 |           606 |
|  22 |            104 |            212 |           252 |           339 |            197 |            413 |           638 |
|  23 |            104 |            220 |           264 |           355 |            197 |            429 |           670 |
|  24 |            104 |            232 |           276 |           371 |            197 |            453 |           702 |
+-----+----------------+----------------+---------------+---------------+----------------+----------------+---------------+

U Counts

+-----+----------------+----------------+---------------+---------------+----------------+----------------+---------------+
|   n |   2_clean_kg24 |   1_clean_kg24 |   n_clean_m15 |   n_dirty_i15 |   2_dirty_kg24 |   1_dirty_kg24 |   1_clean_b95 |
|-----+----------------+----------------+---------------+---------------+----------------+----------------+---------------|
|   3 |             16 |             16 |            16 |            16 |             23 |             23 |            16 |
|   4 |             24 |             24 |            24 |            31 |             39 |             39 |            41 |
|   5 |             32 |             32 |            32 |            39 |             55 |             55 |            52 |
|   6 |             40 |             40 |            40 |            47 |             69 |             71 |            68 |
|   7 |             48 |             48 |            48 |            55 |             85 |             87 |           101 |
|   8 |             56 |             56 |            56 |            63 |            101 |            103 |           117 |
|   9 |             64 |             64 |            64 |            71 |            117 |            119 |           133 |
|  10 |             72 |             72 |            72 |            79 |            133 |            135 |           149 |
|  11 |             80 |             80 |            80 |            87 |            149 |            151 |           165 |
|  12 |             88 |             88 |            88 |            95 |            165 |            167 |           181 |
|  13 |             96 |             96 |            96 |           103 |            181 |            183 |           197 |
|  14 |            104 |            104 |           104 |           111 |            197 |            199 |           213 |
|  15 |            112 |            112 |           112 |           119 |            213 |            215 |           229 |
|  16 |            120 |            120 |           120 |           127 |            229 |            231 |           245 |
|  17 |            128 |            128 |           128 |           135 |            245 |            247 |           261 |
|  18 |            136 |            136 |           136 |           143 |            261 |            263 |           277 |
|  19 |            144 |            144 |           144 |           151 |            277 |            279 |           293 |
|  20 |            152 |            152 |           152 |           159 |            293 |            295 |           309 |
|  21 |            160 |            160 |           160 |           167 |            309 |            311 |           325 |
|  22 |            168 |            168 |           168 |           175 |            325 |            327 |           341 |
|  23 |            176 |            176 |           176 |           183 |            341 |            343 |           357 |
|  24 |            184 |            184 |           184 |           191 |            357 |            359 |           373 |
+-----+----------------+----------------+---------------+---------------+----------------+----------------+---------------+

Code

from qiskit.transpiler import generate_preset_pass_manager
from qiskit.synthesis.multi_controlled.mcx_synthesis import *

pm = generate_preset_pass_manager(optimization_level=2, basis_gates=["cx", "u"])

mcxs = [synth_mcx_2_clean_kg24, synth_mcx_1_clean_kg24, synth_mcx_n_clean_m15, synth_mcx_n_dirty_i15,
       synth_mcx_2_dirty_kg24, synth_mcx_1_dirty_kg24, synth_mcx_1_clean_b95]

mcx_counts = []
for n in range(3, 25):
    cx_counts = {}
    u_counts = {}
    depth = {}
    for mcx_func in mcxs:
        mcx = mcx_func(n)
        qc = pm.run(mcx)
        function_name = mcx_func.__name__.removeprefix("synth_mcx_")
        cx_counts[function_name] = qc.count_ops()['cx']
        u_counts[function_name] = qc.count_ops()['u']
        depth[function_name] = qc.depth()

        ops = qc.count_ops()
        u_count, cx_count = ops.get('u', 0), ops.get('cx', 0)
        mcx_counts.append({"name": function_name, "n": n, "cx_count": cx_count, "u_count": u_count, "depth": qc.depth()})

    print(f"n={n}: {cx_counts}")

@coveralls
Copy link

coveralls commented May 17, 2025

Pull Request Test Coverage Report for Build 15348049412

Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

Details

  • 15 of 15 (100.0%) changed or added relevant lines in 1 file are covered.
  • 54 unchanged lines in 9 files lost coverage.
  • Overall coverage increased (+0.02%) to 87.852%

Files with Coverage Reduction New Missed Lines %
qiskit/circuit/library/pauli_evolution.py 2 96.49%
qiskit/result/sampled_expval.py 2 93.55%
crates/qasm2/src/lex.rs 3 92.98%
qiskit/synthesis/evolution/suzuki_trotter.py 4 90.38%
qiskit/synthesis/evolution/qdrift.py 5 86.49%
crates/qasm2/src/parse.rs 6 97.61%
qiskit/synthesis/evolution/product_formula.py 7 89.9%
qiskit/circuit/quantumcircuitdata.py 10 80.82%
crates/quantum_info/src/sparse_observable/mod.rs 15 94.16%
Totals Coverage Status
Change from base Build 15333013138: 0.02%
Covered Lines: 80407
Relevant Lines: 91526

💛 - Coveralls

Copy link
Member

@ShellyGarion ShellyGarion left a comment

Choose a reason for hiding this comment

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

@patelvyom - this is a great idea to replace all toffoli gates by relative toffolis, and I'm extremely happy to see that the CX counts bounds have improved by 2x!

My main comment is that we already have an rccx method in qiskit and using it could simplify your code, and maybe make it faster (since it's written in rust).

Could you also fix your previous release notes for the plugins?
https://github.com/Qiskit/qiskit/blob/main/releasenotes/notes/add-new-mcx-plugins-2177db9195e2b680.yaml

If you make these changes in the next days, I think this PR could go into qiskit 2.1 release (planned on June 6). Otherwise, it will go into qiskit 2.2 (and require new release notes).
There is no reason to hurry here - it's up to you :)

@patelvyom
Copy link
Contributor Author

@ShellyGarion I've addressed your comments. Let me know if you have more suggestions.

@ShellyGarion ShellyGarion added this to the 2.1.0 milestone May 30, 2025
@ShellyGarion ShellyGarion added the Changelog: None Do not include in changelog label May 30, 2025
Copy link
Member

@ShellyGarion ShellyGarion left a comment

Choose a reason for hiding this comment

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

@patelvyom - thanks for doing all these changes so quickly!
I have one final small comment.

Copy link
Member

@ShellyGarion ShellyGarion left a comment

Choose a reason for hiding this comment

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

This PR enhances #13922 by replacing ccx gates with rccx gates, thus improving the CX count by 2x!
I think it should definitely go into qiskit 2.1 release.
@alexanderivrii - do you have any final comments?

@ShellyGarion ShellyGarion added this pull request to the merge queue May 30, 2025
Merged via the queue into Qiskit:main with commit 6161b56 May 30, 2025
26 checks passed
rahaman-quantum pushed a commit to rahaman-quantum/qiskit that referenced this pull request Jun 20, 2025
* add relative phase toffoli in ccx+x decomp

* update cx counts tests

* update HLS transpiler

* Update qiskit/synthesis/multi_controlled/mcx_synthesis.py

Co-authored-by: Shelly Garion <[email protected]>

* use in-built rccx instead of custom implementation, repalce rccx_x without x with rccx

* use rccx in logn_depth_ladder

* update dosctring

* replace inverse with regular rccx_x

* update synth order in release notes

* use rccx directly

---------

Co-authored-by: Shelly Garion <[email protected]>
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 Community PR PRs from contributors that are not 'members' of the Qiskit repo synthesis
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

5 participants