Skip to content

Conversation

ajavadia
Copy link
Member

Summary

This commit updates the DefaultUnitarySynthesis transpiler pass for the case of 2-qubit unitaries. Now it can target a richer gateset, and picks the lowest-error synthesis option if multiple synthesis exist.

Details and comments

The basis supported here is a single controlled gate of the canonical form (a, 0, 0) or a set of supercontrolled gates of the canonical form (pi/4, b, 0), or both. Other basis decomposers can be added in the future. Each two-qubit basis is paired with every possible one-qubit basis to yield the set of all possible basis to consider.

Example

import math

from qiskit import transpile
from qiskit.transpiler.passes import *
from qiskit.transpiler import PassManager, CouplingMap, Target, InstructionProperties
from qiskit.circuit.library import *
from qiskit.circuit import Parameter

def synthesize_over_target(target):
    pm = PassManager([
        Collect2qBlocks(),
        ConsolidateBlocks(force_consolidate=True),
        UnitarySynthesis(target=target),
        Optimize1qGatesDecomposition(target)
    ])
    qv_t = pm.run(qv_m)
    display(qv_t.draw('mpl', fold=-1, style='iqx'))

num_qubits = 4
qv = QuantumVolume(num_qubits, seed=3)
qv.decompose().draw('mpl', fold=-1, style='iqx')

qv_m = transpile(qv, 
                 coupling_map=CouplingMap.from_line(num_qubits, bidirectional=True),
                 routing_method='sabre', layout_method='sabre', seed_transpiler=2)

# original
qv_m.draw('mpl', fold=-1, style='iqx')

# build Target
target = Target()

theta = Parameter('theta')
phi = Parameter('phi')   
lam = Parameter('lambda')

sx_props = {
    (0,): InstructionProperties(duration=2.88e-8, error=0.00038),
    (1,): InstructionProperties(duration=2.88e-8, error=0.00085),
    (2,): InstructionProperties(duration=2.88e-8, error=0.00093),
}

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

cx_props = {
    (0, 1): InstructionProperties(duration=1.74e-6, error=.03),
    (1, 2): InstructionProperties(duration=1.74e-6, error=.04),
}

target.add_instruction(RZGate(theta), rz_props)
target.add_instruction(SXGate(), sx_props)
target.add_instruction(CXGate(), cx_props, name='cx')

# target 1
synthesize_over_target(target)

rx_props = {
    (0,): InstructionProperties(duration=3.23e-8, error=0.00038),
    (1,): InstructionProperties(duration=3.23e-8, error=0.00085),
    (2,): InstructionProperties(duration=3.23e-8, error=0.00093),
}

ch_props = {
    (0, 1): InstructionProperties(duration=1.74e-6, error=.001),
    (1, 2): InstructionProperties(duration=1.74e-6, error=.003),
}

target.add_instruction(RXGate(theta), rx_props, name='rx')
target.add_instruction(CHGate(), ch_props, name='ch')

# target 2
synthesize_over_target(target)

# add more to the Target
u_props = {
    (0,): InstructionProperties(duration=3.23e-8, error=0.00008),
    (1,): InstructionProperties(duration=3.23e-8, error=0.004),
    (2,): InstructionProperties(duration=3.23e-8, error=0.003),
}

rzz_18_props = {
    (0, 1): InstructionProperties(duration=0.74e-7, error=.001),
    (1, 2): InstructionProperties(duration=0.74e-7, error=.001),
}

rzz_45_props = {
    (0, 1): InstructionProperties(duration=1.04e-6, error=.002),
    (1, 2): InstructionProperties(duration=1.04e-6, error=.002),
}

target.add_instruction(UGate(theta, phi, lam), u_props, name='u')
target.add_instruction(RZZGate(math.pi / 10), rzz_18_props, name='rzz_18')
target.add_instruction(RZZGate(math.pi / 4), rzz_45_props, name='rzz_45')

# target 3
synthesize_over_target(target)

original
image

target 1
image

target 2
image

target 3
image

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

@ajavadia ajavadia added mod: transpiler Issues and PRs related to Transpiler Changelog: New Feature Include in the "Added" section of the changelog Changelog: API Change Include in the "Changed" section of the changelog labels Nov 22, 2022
@ajavadia ajavadia added this to the 0.23.0 milestone Nov 22, 2022
@mtreinish mtreinish self-assigned this Jan 9, 2023
@ewinston ewinston self-assigned this Jan 17, 2023
@mtreinish mtreinish modified the milestones: 0.23.0, 0.24.0 Jan 19, 2023
@ajavadia ajavadia force-pushed the partial-zz branch 2 times, most recently from ca7cf23 to f40ffda Compare January 22, 2023 07:20
@ajavadia ajavadia requested a review from ikkoham as a code owner January 22, 2023 07:20
@ajavadia
Copy link
Member Author

@ewinston @mtreinish I think this is ready, can you have another look please

@coveralls
Copy link

coveralls commented Jan 22, 2023

Pull Request Test Coverage Report for Build 4093415744

  • 342 of 353 (96.88%) changed or added relevant lines in 10 files are covered.
  • 2 unchanged lines in 2 files lost coverage.
  • Overall coverage increased (+0.03%) to 85.271%

Changes Missing Coverage Covered Lines Changed/Added Lines %
qiskit/quantum_info/synthesis/xx_decompose/decomposer.py 11 13 84.62%
qiskit/transpiler/passes/synthesis/unitary_synthesis.py 197 206 95.63%
Files with Coverage Reduction New Missed Lines %
qiskit/quantum_info/synthesis/xx_decompose/decomposer.py 1 91.06%
qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py 1 97.7%
Totals Coverage Status
Change from base Build 4088861036: 0.03%
Covered Lines: 67249
Relevant Lines: 78865

💛 - Coveralls

@ewinston
Copy link
Contributor

ewinston commented Feb 3, 2023

This looks good, although I didn't carefully check the performance, but I suppose that will show up in the automated benchmarks.

@mergify mergify bot merged commit a8f83c4 into Qiskit:main Feb 4, 2023
pranay1990 pushed a commit to pranay1990/qiskit-terra that referenced this pull request Feb 9, 2023
…ets (Qiskit#9175)

* make Optimize1qGatesDecomposition target aware

* choose decomopsition based on fidelity

* tests for the target path

* choosing XXDecomposition

* add known embodiments as a library

* choosing between controlled and supercontrolled decomposers

* add known embodiments. add basis_fidelity to init of XXDecomposer

* set basis_fidelity at init of all decomposers, not per call

* choose euler_basis based on 1q error rates

* make backup_optimizer in XXDecomposer pulse_efficient

* revert changes to one_qubit_euler_decomposer.py

* use Optimize1qGatesDecomposition when UnitarySynthesis hits a 1-qubit unitary

* build all the decomposers, then choose after running them

* add a function for computing circuit error from target

* run all available decomposers, fix synth direction if needed, choose min cost

* xx embodiment for itself

* add ECR embodiment and fix some tests

* add ECR embodiment and fix some tests

* fix preferred_direction

* no decomposition if no basis

* release notes

* remove unnecessary GateDirection from level 3. Add a test for targeting a single fractional gate, no full entangler

* change gate_lengths and gate_errors format, and update _preferred_direction and _error

* remove accidental test duplicates

* small lint fixes

* approximation degree

* rebase

* add approximate=True/False arg to TwoQubitBasisDecomposer

* black

* review comments

* approximation_degree should default to 1, not None

* type hints

* fix a test that was wrong in test_optimize_1q_commutation

* one qubit unitary corner case is decomposed with UnitarySynthesis but not with Optimize1qGatesDecomposition

* one more test for approx

* lint

* release note format
@1ucian0
Copy link
Member

1ucian0 commented Feb 15, 2023

could it be this introduced a regression #9592 ?

mtreinish added a commit to mtreinish/qiskit-core that referenced this pull request Feb 17, 2023
This commit fixes an issue introduced into the UnitarySynthesis pass as
part of Qiskit#9175. In Qiskit#9715 the UnitarySynthesis pass was updated to
consider multiple different target bases and select the best performing
synthesis output found. When UnitarySynthesis is provided a Target
object this involves querying the target for the error rates and
duration of the instructions used. However, currently this lookup
doesn't handle a couple of edge cases in the target data model resulting
from variable width operations and ideal gates (i.e. from a simulator
that don't have error or durations). In those cases some fields in the
internal dictionaries used to store data can be None or the gate object
stored in the target can be a class not an instance of a class. If a
target with either of these properties were used as an input to
UnitarySynthesis the pass would error.

Fixes Qiskit#9592
mergify bot added a commit that referenced this pull request Feb 20, 2023
* Fix target error and duration lookup in UnitarySynthesis

This commit fixes an issue introduced into the UnitarySynthesis pass as
part of #9175. In #9715 the UnitarySynthesis pass was updated to
consider multiple different target bases and select the best performing
synthesis output found. When UnitarySynthesis is provided a Target
object this involves querying the target for the error rates and
duration of the instructions used. However, currently this lookup
doesn't handle a couple of edge cases in the target data model resulting
from variable width operations and ideal gates (i.e. from a simulator
that don't have error or durations). In those cases some fields in the
internal dictionaries used to store data can be None or the gate object
stored in the target can be a class not an instance of a class. If a
target with either of these properties were used as an input to
UnitarySynthesis the pass would error.

Fixes #9592

* Remove superfluous pylint suppression

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Eric-Arellano pushed a commit to Eric-Arellano/qiskit-terra that referenced this pull request Feb 23, 2023
* Fix target error and duration lookup in UnitarySynthesis

This commit fixes an issue introduced into the UnitarySynthesis pass as
part of Qiskit#9175. In Qiskit#9715 the UnitarySynthesis pass was updated to
consider multiple different target bases and select the best performing
synthesis output found. When UnitarySynthesis is provided a Target
object this involves querying the target for the error rates and
duration of the instructions used. However, currently this lookup
doesn't handle a couple of edge cases in the target data model resulting
from variable width operations and ideal gates (i.e. from a simulator
that don't have error or durations). In those cases some fields in the
internal dictionaries used to store data can be None or the gate object
stored in the target can be a class not an instance of a class. If a
target with either of these properties were used as an input to
UnitarySynthesis the pass would error.

Fixes Qiskit#9592

* Remove superfluous pylint suppression

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
mtreinish added a commit to mtreinish/qiskit-core that referenced this pull request Feb 27, 2023
Since Qiskit#9175 merged the UnitarySynthesis pass has been updated to
consider multiple different potential target bases and select the best
performing synthesis output found. When UnitarySynthesis is provided a
Target object this involves querying the target for the error rates and
duration of the instructions used and determining which bases are valid.
As part of this lookup the Operator for the 2q gates in the target is
needed to determine the characteristics of the 2q gates. However, the
code for doing this wasn't considering that some operations in the
target might not have sufficient information to build a unitary
representation of the operation. This could come up with the use of
custom opaque gates in the target that don't have a definition defined
or a matrix defined. This commit fixes this oversight and handles the
case where building an Operator for the gate fails.

Related to #9675 (the underlying issue is in the qiskit-ibm-runtime
package for not mapping the "ecr" string to the "ECRGate" object, so
this won't close that issue).
mergify bot added a commit that referenced this pull request Mar 3, 2023
* Fix UnitarySynthesis with target that contains custom gates

Since #9175 merged the UnitarySynthesis pass has been updated to
consider multiple different potential target bases and select the best
performing synthesis output found. When UnitarySynthesis is provided a
Target object this involves querying the target for the error rates and
duration of the instructions used and determining which bases are valid.
As part of this lookup the Operator for the 2q gates in the target is
needed to determine the characteristics of the 2q gates. However, the
code for doing this wasn't considering that some operations in the
target might not have sufficient information to build a unitary
representation of the operation. This could come up with the use of
custom opaque gates in the target that don't have a definition defined
or a matrix defined. This commit fixes this oversight and handles the
case where building an Operator for the gate fails.

Related to #9675 (the underlying issue is in the qiskit-ibm-runtime
package for not mapping the "ecr" string to the "ECRGate" object, so
this won't close that issue).

* Fix lint

* Only run Operator construction under try block

The error we're trying to catch and handle is if a gate object doesn't
have sufficient information to get it's matrix. This commit updates the
try block to only run on the Operator construction so we don't
potentially mas errors in the TwoQubitWeylDecomposition construction.

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
mtreinish added a commit to mtreinish/qiskit-core that referenced this pull request May 2, 2023
This commit reverts an unecessary breaking API change that was
introduced in Qiskit#9175. In that PR the data type for two arguments,
gate_lengths and gate_errors, that was potentially passed to
plugins was changed. This change was well intentioned as it was
used by the default plugin as part of the changes to the default
plugin made in that PR. But this neglected the downstream effects
for any existing plugin interface users relying on the input to
those fields. Making this change to existing fields would break
any plugins that were using the old data format and is a violation
of the Qiskit stability and deprecation policy. This commit reverts
that change so that gate_lengths and gate_errors contain the same data
format as in previous releases. Instead to facilitate the new
workflow a new fields, gate_lengths_by_qubit and gate_errors_by_qubit,
were added that leverage the new format introduced by Qiskit#9175. By adding
this as new optional fields existing users can continue to work as
before, but the default plugin which requires the different data
format can use the new data type.
kdk pushed a commit that referenced this pull request May 3, 2023
* Undo breaking API change in unitary synthesis plugin interface

This commit reverts an unecessary breaking API change that was
introduced in #9175. In that PR the data type for two arguments,
gate_lengths and gate_errors, that was potentially passed to
plugins was changed. This change was well intentioned as it was
used by the default plugin as part of the changes to the default
plugin made in that PR. But this neglected the downstream effects
for any existing plugin interface users relying on the input to
those fields. Making this change to existing fields would break
any plugins that were using the old data format and is a violation
of the Qiskit stability and deprecation policy. This commit reverts
that change so that gate_lengths and gate_errors contain the same data
format as in previous releases. Instead to facilitate the new
workflow a new fields, gate_lengths_by_qubit and gate_errors_by_qubit,
were added that leverage the new format introduced by #9175. By adding
this as new optional fields existing users can continue to work as
before, but the default plugin which requires the different data
format can use the new data type.

* Update docstring

* Fix copy paste error
mergify bot pushed a commit that referenced this pull request May 3, 2023
* Undo breaking API change in unitary synthesis plugin interface

This commit reverts an unecessary breaking API change that was
introduced in #9175. In that PR the data type for two arguments,
gate_lengths and gate_errors, that was potentially passed to
plugins was changed. This change was well intentioned as it was
used by the default plugin as part of the changes to the default
plugin made in that PR. But this neglected the downstream effects
for any existing plugin interface users relying on the input to
those fields. Making this change to existing fields would break
any plugins that were using the old data format and is a violation
of the Qiskit stability and deprecation policy. This commit reverts
that change so that gate_lengths and gate_errors contain the same data
format as in previous releases. Instead to facilitate the new
workflow a new fields, gate_lengths_by_qubit and gate_errors_by_qubit,
were added that leverage the new format introduced by #9175. By adding
this as new optional fields existing users can continue to work as
before, but the default plugin which requires the different data
format can use the new data type.

* Update docstring

* Fix copy paste error

(cherry picked from commit 72e7481)
mtreinish added a commit that referenced this pull request May 3, 2023
… (#10075)

* Undo breaking API change in unitary synthesis plugin interface

This commit reverts an unecessary breaking API change that was
introduced in #9175. In that PR the data type for two arguments,
gate_lengths and gate_errors, that was potentially passed to
plugins was changed. This change was well intentioned as it was
used by the default plugin as part of the changes to the default
plugin made in that PR. But this neglected the downstream effects
for any existing plugin interface users relying on the input to
those fields. Making this change to existing fields would break
any plugins that were using the old data format and is a violation
of the Qiskit stability and deprecation policy. This commit reverts
that change so that gate_lengths and gate_errors contain the same data
format as in previous releases. Instead to facilitate the new
workflow a new fields, gate_lengths_by_qubit and gate_errors_by_qubit,
were added that leverage the new format introduced by #9175. By adding
this as new optional fields existing users can continue to work as
before, but the default plugin which requires the different data
format can use the new data type.

* Update docstring

* Fix copy paste error

(cherry picked from commit 72e7481)

Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
king-p3nguin pushed a commit to king-p3nguin/qiskit-terra that referenced this pull request May 22, 2023
)

* Fix UnitarySynthesis with target that contains custom gates

Since Qiskit#9175 merged the UnitarySynthesis pass has been updated to
consider multiple different potential target bases and select the best
performing synthesis output found. When UnitarySynthesis is provided a
Target object this involves querying the target for the error rates and
duration of the instructions used and determining which bases are valid.
As part of this lookup the Operator for the 2q gates in the target is
needed to determine the characteristics of the 2q gates. However, the
code for doing this wasn't considering that some operations in the
target might not have sufficient information to build a unitary
representation of the operation. This could come up with the use of
custom opaque gates in the target that don't have a definition defined
or a matrix defined. This commit fixes this oversight and handles the
case where building an Operator for the gate fails.

Related to #9675 (the underlying issue is in the qiskit-ibm-runtime
package for not mapping the "ecr" string to the "ECRGate" object, so
this won't close that issue).

* Fix lint

* Only run Operator construction under try block

The error we're trying to catch and handle is if a gate object doesn't
have sufficient information to get it's matrix. This commit updates the
try block to only run on the Operator construction so we don't
potentially mas errors in the TwoQubitWeylDecomposition construction.

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
king-p3nguin pushed a commit to king-p3nguin/qiskit-terra that referenced this pull request May 22, 2023
…t#10066)

* Undo breaking API change in unitary synthesis plugin interface

This commit reverts an unecessary breaking API change that was
introduced in Qiskit#9175. In that PR the data type for two arguments,
gate_lengths and gate_errors, that was potentially passed to
plugins was changed. This change was well intentioned as it was
used by the default plugin as part of the changes to the default
plugin made in that PR. But this neglected the downstream effects
for any existing plugin interface users relying on the input to
those fields. Making this change to existing fields would break
any plugins that were using the old data format and is a violation
of the Qiskit stability and deprecation policy. This commit reverts
that change so that gate_lengths and gate_errors contain the same data
format as in previous releases. Instead to facilitate the new
workflow a new fields, gate_lengths_by_qubit and gate_errors_by_qubit,
were added that leverage the new format introduced by Qiskit#9175. By adding
this as new optional fields existing users can continue to work as
before, but the default plugin which requires the different data
format can use the new data type.

* Update docstring

* Fix copy paste error
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 priority: medium
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants