Skip to content

Conversation

@mtreinish
Copy link
Member

Summary

This commit optimizes the implementation of the LitinskiTransformation pass. The improvements fall into a couple of categories, but most of the runtime performance improvements will come from removing unnecessary allocations.

From a quick glance the Clifford struct looks like it could also use a similar once over, mostly to get it to leverage Qiskit's types more effectively if nothing else. But I kept the changes there minimal for this commit and only modified the method used by The LitinskiTransformation directly.

Details and comments

This commit optimizes the implementation of the LitinskiTransformation
pass. The improvements fall into a couple of categories, but most of the
runtime performance improvements will come from removing unecessary
allocations.

From a quick glance the Clifford struct looks like it could also use a
similar once over, mostly to get it to leverage Qiskit's types more
effectively if nothing else. But I kept the changes there minimal for
this commit and only modified the method used by The
LitinskiTransformation directly.
@mtreinish mtreinish added this to the 2.3.0 milestone Nov 7, 2025
@mtreinish mtreinish requested a review from a team as a code owner November 7, 2025 20:09
@mtreinish mtreinish added performance Changelog: None Do not include in changelog Rust This PR or issue is related to Rust code in the repository fault tolerance related to fault tolerance compilation labels Nov 7, 2025
@github-project-automation github-project-automation bot moved this to Ready in Qiskit 2.3 Nov 7, 2025
@qiskit-bot
Copy link
Collaborator

One or more of the following people are relevant to this code:

  • @Qiskit/terra-core

@mtreinish
Copy link
Member Author

To benchmark this I used the benchmark @alexanderivrii described in the PR summary on #14753 with this script:

import statistics
import time

from qiskit.converters import circuit_to_dag
from qiskit.circuit.library import QFTGate
from qiskit.transpiler.passes import LitinskiTransformation
from qiskit.transpiler import Target
from qiskit import transpile, QuantumCircuit

litinski = LitinskiTransformation()

i = 2
while i <= 1024:

    qft = QuantumCircuit(i)
    qft.append(QFTGate(i), qft.qubits)
    target = Target.from_configuration(["cx", "sx", "rz"], i)
    tqft = transpile(qft, target=target)
    dag = circuit_to_dag(tqft, False)
    times = []
    for _ in range(10):
        start = time.perf_counter()
        litinski.run(dag)
        stop = time.perf_counter()
        times.append(stop - start)
    print(f"nqubits: {i}, runtime: {statistics.geometric_mean(times)}")
    i = i * 2

It yielded these results on my local system:
litinski

@coveralls
Copy link

coveralls commented Nov 7, 2025

Pull Request Test Coverage Report for Build 19208500951

Details

  • 145 of 146 (99.32%) changed or added relevant lines in 2 files are covered.
  • 3 unchanged lines in 3 files lost coverage.
  • Overall coverage increased (+0.03%) to 88.188%

Changes Missing Coverage Covered Lines Changed/Added Lines %
crates/transpiler/src/passes/litinski_transformation.rs 124 125 99.2%
Files with Coverage Reduction New Missed Lines %
crates/circuit/src/parameter/symbol_expr.rs 1 73.27%
crates/qasm2/src/lex.rs 1 92.54%
crates/transpiler/src/passes/litinski_transformation.rs 1 96.43%
Totals Coverage Status
Change from base Build 19206691463: 0.03%
Covered Lines: 94298
Relevant Lines: 106928

💛 - Coveralls

@alexanderivrii
Copy link
Member

Thanks @mtreinish! I have just now run your script for the most problematic case of QFTGate(1024) (with the only addition of also printing the runtime for each individual run) and I see no significant difference between the main branch, #15217 (which extends the support to PauliProductMeasurement instructions and also refactors the code a bit, though this refactoring is orthogonal to your changes), and this PR. For each of the 3 code versions it takes about 43 seconds to run the transform. For reference, this is done on my mac laptop and python 3.13.

In any case, for the interest of helping @Cryoris to prepare for QDC, I would suggest merging #15217 first, and then merging your PR.

Besides adapting to the rebase this also improves the SparseObservable
construction.
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 fault tolerance related to fault tolerance compilation performance Rust This PR or issue is related to Rust code in the repository

Projects

Status: Ready

Development

Successfully merging this pull request may close these issues.

4 participants