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

better single-qubit gate optimization workflow #8192

Open
ajavadia opened this issue Jun 16, 2022 · 4 comments
Open

better single-qubit gate optimization workflow #8192

ajavadia opened this issue Jun 16, 2022 · 4 comments
Labels
type: feature request New feature or request

Comments

@ajavadia
Copy link
Member

What should we add?

There has been some work recently in #7579 and #8178 to enable optimization of chains of single-qubit gates when they contain parameters. Previously qiskit only did this optimization for numeric values.

While useful, the current procedure is still a bit ad-hoc. It enables optimizing:

  • a chain of rz
  • a chain of rx
  • a chain of ry
  • a chain of p
  • a chain of u1
  • a chain of u2 (plus possible u1)

Instead I suggest the following workflow:

  1. For one, we should not have two passes for this Optimize1qGates and Optimize1qGatesDecomposition. The former should be deprecated.

  2. Then, the pass should collect and consolidate any chain of single-qubit gates into a 2x2 unitary matrix. Regardless of what the underlying gates are (rx, ry, rz, u, u2, s, t, ...), the chain should be represented as a single 2x2 matrix. This should be fast to compute even for symbolic math.

  3. Then we build synthesis routines to go from a 2x2 matrix to any of the basis of interest:

  • U1 or RZ/P in case the result is a diagonal
  • U2 or RZ-SX-RZ in case the matrix is of a particular shape
  • U3 or U in case the matrix is general
  • RZ-RX-RY or RX-RZ-RX or RZ-RY-RZ or ...(any combination of two pauli rotations), in case this decomposition is desired. We already have code for this in quantum_info/synthesis/one_qubit_euler_decomposition
  • RZ-SX-RZ-SX-RZ or RZ-SX-RZ in case these gates are in the basis
  • Clifford + T in case a fault-tolerant basis is required

The point is that single qubit gate synthesis is easy and known. It's also small and efficient to compute the full matrix. So instead of lots of ad-hoc rules for combining gates, we should just make a generic U, then go to the desired basis from there.

@ajavadia ajavadia added the type: feature request New feature or request label Jun 16, 2022
@mtreinish
Copy link
Member

I agree the single qubit gate chain path should be unified and improved and doing things on an ad-hoc basis just leads to us missing things. For the specific steps:

  1. I'm fine with this, but we've been reluctant to deprecate transpiler passes in general though even if they've been superseded by something better. This came up recently again with CSPLayout vs VF2Layout and we decided to just keep CSPLayout even if it's not as good as people might be depending on it. We don't have to use it in the preset passmanagers. I think for optimize 1q gates though, there really isn't a use case unless you have a target basis with u and then it might be marginally faster.

  2. This mostly already exists as it's what Optimize1qGatesDecomposition does internally. The thing that's missing is support for parameters. The fundamental issue around doing this is that the matrix is represented as a numpy array and we're not able to mix types in a numpy array. Also numpy doesn't have support for dealing with ParameterExpression as a numeric element (we can put it in an object dtype array but that limits what it can be used for as it's just an array of pointers to python objects and isn't really useful here). There really isn't a good array representation that supports symbolic elements. Sympy has representations of this but it's super slow in my experience and I'm not sure we'd want to go down that path and I'm pretty sure that symengine doesn't offer equivalent functionality.

  3. Ideally I'd like to make this pluggable somehow too so that backends with custom basis don't have to rewrite the synthesis pass from scratch and can just leverage the machinery around the pass and insert a custom target basis to the pass directly.

@nonhermitian
Copy link
Contributor

nonhermitian commented Jun 16, 2022

So as discussed with @ajavadia this can be symbolically, or in another way where the 4 needed parameters are stored in lists, but not evaluated. Because the insertion order would determine the order in which the unitaries were composed, one could iterate over the list, binding parameters, and computing the resultant angles as you go via a regular numerical function eval. Some fine tuning of this idea is probably needed, but one can work around the need for matrices and arrays of parameters.

@rafal-pracht
Copy link
Contributor

Maybe we can change in the Quaternion class (qiskit.quantum_info.synthesis.quaternion) to support symbols. In that case, we can convert any gate to u3, and then using Euler angles we can merge gates. The final u3 can be in easy way decomposed into base gates.

@nonhermitian
Copy link
Contributor

So yeah one could do that, but then you would really need to have a way of symbolically having a function vec3 = f(vec2, vec1) that can be expressed in string form and using vectors that are passed around. Otherwise you couldn't lazy eval the expression at the end. If this is used generically then the only symbolics one needs is the parameter names to bind to. Other than that, the insertion order of something like a list tells you how to compose the unitaries. After binding this could just be iteratively evaluated. Because these are all effectively small matrix / vector computations, doing the final numerics in rust (or the like) is going to be beneficial to remove function call overheads.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: feature request New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants