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

Update Optimize1qGatesDecomposition to be Target aware #8917

Merged
merged 20 commits into from
Nov 17, 2022

Conversation

ajavadia
Copy link
Member

@ajavadia ajavadia commented Oct 16, 2022

Summary

Updating the Optimize1qGatesDecomposition pass to take into account Target if available. This means that it chooses the best decomposition adaptively per qubit, and tries to minimize error.
For example, it would convert a RX-RZ-RX sequence to a RZ-RX-RZ sequence over the same basis, if RZ is cheaper. Previously the cost heuristic was something simple like the length of the sequence.

import math
from qiskit.transpiler import PassManager, Target, InstructionProperties
from qiskit.circuit.library import RZGate, RXGate, SXGate, CXGate
from qiskit.circuit import QuantumCircuit, Parameter, Measure
from qiskit.transpiler.passes import Optimize1qGatesDecomposition

θ = Parameter('θ')

rx_props = {
    (0,) : InstructionProperties(duration=0.5e-8, error=.00025)
}

rz_props = {
    (0,): InstructionProperties(duration=0, error=0)
}

target = Target()
target.add_instruction(RZGate(θ), rz_props, name='rz')
target.add_instruction(RXGate(θ), rx_props, name='rx')

circuit = QuantumCircuit(1)
circuit.sx(0)
circuit.barrier()
circuit.u(.1, .2, .3, 0)
circuit.barrier()
circuit.u2(.2, .3, 0)
circuit.barrier()
circuit.rx(.2, 0)
circuit.rz(.3, 0)
circuit.rx(.2, 0)
circuit.barrier()
circuit.u3(0, 0, math.pi/4, 0)
circuit.barrier()
circuit.rz(0, 0)
circuit.barrier()
circuit.rx(.75, 0)
circuit.rx(-.75, 0)
pm = PassManager(Optimize1qGatesDecomposition(target=target))
new_circuit = pm.run(circuit)

print('before:')
print(circuit)

print('after:')
print(new_circuit)
before:
   ┌────┐ ░ ┌────────────────┐ ░ ┌─────────────┐ ░ ┌─────────┐┌─────────┐┌─────────┐ ░ ┌─────────────┐ ░ ┌───────┐ ░ ┌──────────┐┌───────────┐
q: ┤ √X ├─░─┤ U(0.1,0.2,0.3) ├─░─┤ U2(0.2,0.3) ├─░─┤ Rx(0.2) ├┤ Rz(0.3) ├┤ Rx(0.2) ├─░─┤ U3(0,0,π/4) ├─░─┤ Rz(0) ├─░─┤ Rx(0.75) ├┤ Rx(-0.75) ├
   └────┘ ░ └────────────────┘ ░ └─────────────┘ ░ └─────────┘└─────────┘└─────────┘ ░ └─────────────┘ ░ └───────┘ ░ └──────────┘└───────────┘

after:
global phase: 1.6781
   ┌─────────┐ ░ ┌─────────────┐┌─────────┐┌────────────┐ ░ ┌─────────────┐┌─────────┐┌────────────┐ ░ ┌───────────┐┌─────────────┐┌───────────┐ ░ ┌─────────┐ ░  ░ 
q: ┤ Rx(π/2) ├─░─┤ Rz(-1.2708) ├┤ Rx(0.1) ├┤ Rz(1.7708) ├─░─┤ Rz(-1.2708) ├┤ Rx(π/2) ├┤ Rz(1.7708) ├─░─┤ Rz(0.153) ├┤ Rx(0.39545) ├┤ Rz(0.153) ├─░─┤ Rz(π/4) ├─░──░─
   └─────────┘ ░ └─────────────┘└─────────┘└────────────┘ ░ └─────────────┘└─────────┘└────────────┘ ░ └───────────┘└─────────────┘└───────────┘ ░ └─────────┘ ░  ░ 

@ajavadia ajavadia requested a review from a team as a code owner October 16, 2022 19:55
@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:

  • @Qiskit/terra-core

@mtreinish mtreinish self-assigned this Oct 16, 2022
@ajavadia ajavadia force-pushed the target-in-optimize1qgatesdecomposition branch from 7917f7e to c72f4c6 Compare October 18, 2022 04:27
@coveralls
Copy link

coveralls commented Oct 18, 2022

Pull Request Test Coverage Report for Build 3492084298

  • 62 of 62 (100.0%) changed or added relevant lines in 4 files are covered.
  • 1 unchanged line in 1 file lost coverage.
  • Overall coverage increased (+0.003%) to 84.579%

Files with Coverage Reduction New Missed Lines %
qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py 1 98.72%
Totals Coverage Status
Change from base Build 3491436652: 0.003%
Covered Lines: 62511
Relevant Lines: 73908

💛 - Coveralls

@t-imamichi
Copy link
Member

I'm assigned as reviewer, but I'm not familiar with the transpiler pass. @itoko -san may be more appropriate.

@ajavadia ajavadia force-pushed the target-in-optimize1qgatesdecomposition branch from c72f4c6 to d6ad95e Compare November 5, 2022 01:51
@ajavadia ajavadia added this to the 0.23.0 milestone Nov 5, 2022
Copy link
Member

@mtreinish mtreinish left a comment

Choose a reason for hiding this comment

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

Overall this LGTM, thanks for doing this. I especially like that we're factoring the error rates into how we selection a decomposition now. I have a couple of small inline questions but besides those minor details I think this should be good to merge.

qiskit/transpiler/target.py Outdated Show resolved Hide resolved
test/python/compiler/test_transpiler.py Outdated Show resolved Hide resolved
test/python/compiler/test_transpiler.py Show resolved Hide resolved
Copy link
Member

@mtreinish mtreinish 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, I think this mostly LGTM now, I just caught one potential performance issue inline (the same one in both passes). Once that's fixed I think I'll be good to approve and merge this.

@ajavadia ajavadia force-pushed the target-in-optimize1qgatesdecomposition branch from 4322296 to f26ccdf Compare November 17, 2022 17:02
mtreinish
mtreinish previously approved these changes Nov 17, 2022
Copy link
Member

@mtreinish mtreinish left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for the quick update.

@mtreinish mtreinish added automerge Changelog: New Feature Include in the "Added" section of the changelog mod: transpiler Issues and PRs related to Transpiler labels Nov 17, 2022
@mergify mergify bot merged commit 34ee9a9 into Qiskit:main Nov 17, 2022
mtreinish added a commit to mtreinish/qiskit-core that referenced this pull request Nov 22, 2022
This commit ports the per basis parameter calculation from python to
rust. In looking at the runtime performance regression caused by Qiskit#8917
the majority is just that we're doing more work synthesizing to more
available basis to potentially produce better quality results. Profiling
the transpiler pass shows we're spending a non-trivial amount of time in
numpy/scipy (depending on whether it's before or after Qiskit#9179) computing
the determinant of the unitary. This is likely because those determinant
functions are designed to work with an arbitrarily large square matrix
while for the 1 qubit decomposer we're only ever working with a 2x2.
To remove this overhead this commit writes a dedicated rust function to
compute the determinant of a 2x2 complex matrix and then also adds
dedicated functions to calculate the angles for given basis to rust
as we can easily just return the end result from rust.

Related Qiskit#8774
mtreinish added a commit to mtreinish/qiskit-core that referenced this pull request Nov 22, 2022
This commit ports the per basis parameter calculation from python to
rust. In looking at the runtime performance regression caused by Qiskit#8917
the majority is just that we're doing more work synthesizing to more
available basis to potentially produce better quality results. Profiling
the transpiler pass shows we're spending a non-trivial amount of time in
numpy/scipy (depending on whether it's before or after Qiskit#9179) computing
the determinant of the unitary. This is likely because those determinant
functions are designed to work with an arbitrarily large square matrix
while for the 1 qubit decomposer we're only ever working with a 2x2.
To remove this overhead this commit writes a dedicated rust function to
compute the determinant of a 2x2 complex matrix and then also adds
dedicated functions to calculate the angles for given basis to rust
as we can easily just return the end result from rust.

Related Qiskit#8774
mergify bot pushed a commit that referenced this pull request Dec 2, 2022
* Oxidize parameter calculation for OneQubitEulerDecomposer

This commit ports the per basis parameter calculation from python to
rust. In looking at the runtime performance regression caused by #8917
the majority is just that we're doing more work synthesizing to more
available basis to potentially produce better quality results. Profiling
the transpiler pass shows we're spending a non-trivial amount of time in
numpy/scipy (depending on whether it's before or after #9179) computing
the determinant of the unitary. This is likely because those determinant
functions are designed to work with an arbitrarily large square matrix
while for the 1 qubit decomposer we're only ever working with a 2x2.
To remove this overhead this commit writes a dedicated rust function to
compute the determinant of a 2x2 complex matrix and then also adds
dedicated functions to calculate the angles for given basis to rust
as we can easily just return the end result from rust.

Related #8774

* Eliminate python function for staticmethod definition

This commit removes one layer of function calls for the
OneQubitEulerDecomposer's staticmethods for calculating parameters.
Previously, there was a python function which called an inner rust
function, this eliminates one layer and attaches the rust function
directly as a static method to the class definition.
Cryoris pushed a commit to Cryoris/qiskit-terra that referenced this pull request Jan 12, 2023
* make Optimize1qGatesDecomposition target aware

* choose decomopsition based on fidelity

* fix test that assumed cost of u3 vs. u1 to now rely on target

* always replace identity with empty

* black

* remove a bunch of unnecessary basis translations in tests

* tests for the target path

* add to preset passmanagers

* fixup Optimize1qGatesSimpleCommutation to work with new Optimize1qGatesDecomposition

* dont access duration and error unconditionally

* black

* more docs

* lint

* simplify test

* work around not being able to filter global gates by qubit

* review comments

* add a test for the case of no errors specified in target: pick shortest decomp.

* performance for qubit index lookup

* black

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Cryoris pushed a commit to Cryoris/qiskit-terra that referenced this pull request Jan 12, 2023
* Oxidize parameter calculation for OneQubitEulerDecomposer

This commit ports the per basis parameter calculation from python to
rust. In looking at the runtime performance regression caused by Qiskit#8917
the majority is just that we're doing more work synthesizing to more
available basis to potentially produce better quality results. Profiling
the transpiler pass shows we're spending a non-trivial amount of time in
numpy/scipy (depending on whether it's before or after Qiskit#9179) computing
the determinant of the unitary. This is likely because those determinant
functions are designed to work with an arbitrarily large square matrix
while for the 1 qubit decomposer we're only ever working with a 2x2.
To remove this overhead this commit writes a dedicated rust function to
compute the determinant of a 2x2 complex matrix and then also adds
dedicated functions to calculate the angles for given basis to rust
as we can easily just return the end result from rust.

Related Qiskit#8774

* Eliminate python function for staticmethod definition

This commit removes one layer of function calls for the
OneQubitEulerDecomposer's staticmethods for calculating parameters.
Previously, there was a python function which called an inner rust
function, this eliminates one layer and attaches the rust function
directly as a static method to the class definition.
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
None yet
Development

Successfully merging this pull request may close these issues.

5 participants