Currently there is a unitary_synthesis_method argument to transpile() which switches the decomposition method when unitaries are encountered in the circuit.
But I think we need to split 1q vs. 2q vs. generic unitary synthesis. This may lead to too many args. So I'm fine dropping the arg and allowing alternative way to specify desired methods, as I explain below.
But basically 1q and 2q and generic unitary synthesis have been studied separately and they have very different methods.
In qiskit currently:
SolovayKitaev (sk) and OneQubitEulerDecomposer (euler) are only 1q.
TwoQubitWeylDecomposer (weyl) and XXDecomposer (xx) are only 2q.
Isometry[^1] (ccd) and Shannon (qsd) and ApproximateQuantumCompiler (aqc) are generic.
Generally decompositions of higher-order unitaries use smaller-unitary synthesis methods within them, so setting them separately has the advantage of signaling which method should be internally used when recursing on unitaries during synthesis.
In terms of how the user can select between these, I think there are 3 options (not necessarily mutually exclusive).
Simplest would be to just have unitary_synthesis_method_1q and unitary_synthesis_method_2q added to the current list of transpile args. For the generic unitary_synthesis_method I think we should have options ccd and qsd and aqc and remove 'default'.
When a unitary is added to a circuit the desired method can be tagged onto it like metadata. This allows the user to specify the intent during programming of the circuit itself and e.g. decompose two unitaries using two different methods. This would be consistent with the pragmas being developed as part of OpenQASM 3.
Automatically choose. For example we know aqc is slow but gives better results than the other ones, so it can be used in level 3. Or the basis_gates can dictate the method, for example if the basis is 's', 'h', 't' then only sk makes sense. If the basis is 'zx30', 'zx45', only the xx method makes sense. Other methods cannot target these bases.
[^1]: we currently refer to this as isometry but really the name should be ccd (column-by-colum decomposition). The isometry paper this is based on has two methods (ccd and csd (cosine-sine decomposition)) and only the first one is implemented in qiskit).
What should we add?
Currently there is a
unitary_synthesis_method
argument totranspile()
which switches the decomposition method when unitaries are encountered in the circuit.But I think we need to split 1q vs. 2q vs. generic unitary synthesis. This may lead to too many args. So I'm fine dropping the arg and allowing alternative way to specify desired methods, as I explain below.
But basically 1q and 2q and generic unitary synthesis have been studied separately and they have very different methods. In qiskit currently:
SolovayKitaev
(sk) andOneQubitEulerDecomposer
(euler) are only 1q.TwoQubitWeylDecomposer
(weyl) andXXDecomposer
(xx) are only 2q.Isometry
[^1] (ccd) andShannon
(qsd) andApproximateQuantumCompiler
(aqc) are generic.Generally decompositions of higher-order unitaries use smaller-unitary synthesis methods within them, so setting them separately has the advantage of signaling which method should be internally used when recursing on unitaries during synthesis.
In terms of how the user can select between these, I think there are 3 options (not necessarily mutually exclusive).
unitary_synthesis_method_1q
andunitary_synthesis_method_2q
added to the current list of transpile args. For the genericunitary_synthesis_method
I think we should have optionsccd
andqsd
andaqc
and remove 'default'.basis_gates
can dictate the method, for example if the basis is's', 'h', 't'
then onlysk
makes sense. If the basis is'zx30', 'zx45'
, only thexx
method makes sense. Other methods cannot target these bases.[^1]: we currently refer to this as isometry but really the name should be
ccd
(column-by-colum decomposition). The isometry paper this is based on has two methods (ccd and csd (cosine-sine decomposition)) and only the first one is implemented in qiskit).