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

State Preparation Circuit Synthesis via Matrix Product State Decomposition #1616

Open
1 task done
1tnguyen opened this issue May 6, 2024 · 17 comments
Open
1 task done
Labels
enhancement New feature or request UnitaryHack Good issue for UnitaryHack

Comments

@1tnguyen
Copy link
Collaborator

1tnguyen commented May 6, 2024

Required prerequisites

  • Search the issue tracker to check if your feature has already been mentioned or rejected in other issues.

Describe the feature

Background

State preparation is an important class of quantum circuits: given the complex amplitude state vector/wave function, synthesize a quantum circuit to prepare that state.

Exact methods exist for this decomposition, e.g., see [1, Sec. 4] or [2] (implemented in https://github.com/NVIDIA/cuda-quantum/blob/main/runtime/cudaq/builder/kernels.h#L62)

An alternative approach is to decompose the input state vector into the Matrix Product State form. Then, there are protocols for converting those MPS tensors into shallow-depth circuits [3, 4].

Description

Develop an MPS-based state preparation module for CUDA-Q.

At a minimum viable prototype level, this can be implemented as a circuit builder module (similar to https://github.com/NVIDIA/cuda-quantum/blob/main/runtime/cudaq/builder/kernels.h#L62) to demonstrate the correctness of the protocol. Ideally, this will eventually be converted to a CUDA-Q MLIR circuit synthesis pass.

The implementation needs to be customizable by the target state preparation fidelity and/or the number of circuit layers.

The basic decomposition is described in [5]. The proposed optimization protocol in [3] can also be considered.

For example, Figure 1 from [4] depicts the high-level decomposition protocol

image

Resources

State vector to MPS tensor decomposition procedure.

References

[1] https://arxiv.org/abs/quant-ph/0406176v5

[2] https://arxiv.org/pdf/quant-ph/0407010

[3] https://arxiv.org/pdf/2209.00595

[4] https://arxiv.org/abs/2303.01562

[5] https://arxiv.org/pdf/1908.07958

@1tnguyen 1tnguyen added enhancement New feature or request UnitaryHack Good issue for UnitaryHack labels May 6, 2024
@ACE07-Sev
Copy link

Greetings there,

Hope you are well. Could you kindly expand a bit more on this?
"Ideally, this will eventually be converted to a CUDA-Q MLIR circuit synthesis pass."

@1tnguyen
Copy link
Collaborator Author

1tnguyen commented Jun 3, 2024

Greetings there,

Hope you are well. Could you kindly expand a bit more on this? "Ideally, this will eventually be converted to a CUDA-Q MLIR circuit synthesis pass."

Hi @ACE07-Sev,

Glad that you're interested in this project.

As you may know, CUDA-Q uses MLIR as its internal IR representation. One of the high-level features that this project aims to support is quantum circuit synthesis for state preparation. Specifically, CUDA-Q would have an IR node representing quantum state initialization (e.g., see this init_state op in our development branch).

The algorithm developed in this project would eventually be implemented as a Quake IR decomposition/synthesis pass (e.g., very similar to the existing gate decomposition passes)

Please let us know if you have any other questions.

@ACE07-Sev
Copy link

Thank you for the kind explanation. I guess my question is if this (beyond the UnitaryHack) is going to be only for state preparation (synthesis of statevectors, not arbitrary quantum circuits)?

Because gate decomposition is usually more for operator synthesis. Would this do operator synthesis as well?

@1tnguyen
Copy link
Collaborator Author

1tnguyen commented Jun 3, 2024

Thank you for the kind explanation. I guess my question is if this (beyond the UnitaryHack) is going to be only for state preparation (synthesis of statevectors, not arbitrary quantum circuits)?

The immediate objective of this project is state preparation. It shares many commonalities with operator/unitary matrix synthesis (e.g., via the matrix product operator (MPO) representation of a unitary matrix, etc.) but operator synthesis is not part of the feature request.

Because gate decomposition is usually more for operator synthesis. Would this do operator synthesis as well?

We don't need to do generic operator synthesis in this project. The state preparation algorithm needs some specific matrix to gate sequence conversion as depicted in the attached figure.

I hope that it helps.

@ACE07-Sev
Copy link

I see, I just wanted to have some context for whether you were also shooting for MPO synthesis since I'm also aiming to do that in the near future.

Cool, I have the code done using qiskit, but since I'm on Windows, I'm having some trouble setting up CUDAQ. I'll see if I can set it up ASAP and rewrite the code with CUDAQ.

@ACE07-Sev
Copy link

Quick question, can I use quimb in my implementation?

@1tnguyen
Copy link
Collaborator Author

1tnguyen commented Jun 7, 2024

Quick question, can I use quimb in my implementation?

Hi @ACE07-Sev,

We'd prefer to minimize third-party dependency as much as we can, especially if it is a Python package. This is because we'll need to support it in C++ as well.

If you have started working on this with quimb as a dependency, I recommend that you try to isolate it in some wrapper/helper module. For example, only expose the functionality you need from quimb as standalone helper functions. That way you can continue the implementation and reimplement those helpers without quimb at a later time.

@1tnguyen
Copy link
Collaborator Author

Hi @ACE07-Sev,
How are you doing with this project?
If you have some code/partial implementation, please feel free to post a PR.
We can iterate over the PR.

@ACE07-Sev
Copy link

Greetings there,

Hope you are well. I am currently translating the code I have to CUDAQ. At the moment, I'd like to know how I can resolve #1773. I'll do my best to make a PR very soon.

@1tnguyen
Copy link
Collaborator Author

Greetings there,

Hope you are well. I am currently translating the code I have to CUDAQ. At the moment, I'd like to know how I can resolve #1773. I'll do my best to make a PR very soon.

Please see my reply in #1773 and let me know if you have any questions. Looking forward to seeing your contribution.

@ACE07-Sev
Copy link

I saw it, thank you very much! I need one more thing before I can finish the translation. How can I do a unitary gate in CUDAQ? This is where one would pass a unitary matrix and qubit indices it would be applied to, and it would get transpiled to the gates. Equivalent of this in qiskit is

circuit = QuantumCircuit(3, 3)
unitary_matrix = SOME_UNITARY_MATRIX
circuit.unitary(unitary_matrix, [0, 1, 2])

@ACE07-Sev
Copy link

Oh, and also how to add a U3 gate?

@1tnguyen
Copy link
Collaborator Author

I saw it, thank you very much! I need one more thing before I can finish the translation. How can I do a unitary gate in CUDAQ? This is where one would pass a unitary matrix and qubit indices it would be applied to, and it would get transpiled to the gates. Equivalent of this in qiskit is

circuit = QuantumCircuit(3, 3)
unitary_matrix = SOME_UNITARY_MATRIX
circuit.unitary(unitary_matrix, [0, 1, 2])

Currently, we don't support arbitrary unitary matrix synthesis. You'd need to decompose it as gates.

Re: u3 gate. This is an example:

kernel.u3(np.pi, np.pi, np.pi / 2, q)

@ACE07-Sev
Copy link

So, once I finish the translation, I'm going to first make a notebook in my PR to show the functional code, and then under your guidance I will implement it in the native style of cudaq. Is that feasible for you?

@ACE07-Sev
Copy link

I see. Am I allowed to use qiskit to transpile it first then?

@ACE07-Sev
Copy link

I saw it, thank you very much! I need one more thing before I can finish the translation. How can I do a unitary gate in CUDAQ? This is where one would pass a unitary matrix and qubit indices it would be applied to, and it would get transpiled to the gates. Equivalent of this in qiskit is

circuit = QuantumCircuit(3, 3)
unitary_matrix = SOME_UNITARY_MATRIX
circuit.unitary(unitary_matrix, [0, 1, 2])

Currently, we don't support arbitrary unitary matrix synthesis. You'd need to decompose it as gates.

Re: u3 gate. This is an example:

kernel.u3(np.pi, np.pi, np.pi / 2, q)

I can't seem to do it. When I run it, it gives this error

Cell In[5], [line 21](vscode-notebook-cell:?execution_count=5&line=21)
     [18](vscode-notebook-cell:?execution_count=5&line=18) def U3(self,
     [19](vscode-notebook-cell:?execution_count=5&line=19)        angles,
     [20](vscode-notebook-cell:?execution_count=5&line=20)        qubit_index: int) -> None:
---> [21](vscode-notebook-cell:?execution_count=5&line=21)     self.circuit.u3(angles[0], angles[1], angles[2], self.qr[qubit_index])

AttributeError: 'PyKernel' object has no attribute 'u3'

@1tnguyen
Copy link
Collaborator Author

1tnguyen commented Jun 12, 2024

This U3 feature is scheduled for the next release (v0.8).
It's only available in the nightly docker container but not the Python wheel.
For your circuit builder model, you can use the decomposed form, if using 0.7.x wheels e.g.,

def U3(self, angles, qubit_index: int) -> None:
   self.circuit.rz(angles[2], self.qr[qubit_index])
   self.circuit.rx(np.pi/2, self.qr[qubit_index])
   self.circuit.rz(angles[0], self.qr[qubit_index])
   self.circuit.rx(-np.pi/2, self.qr[qubit_index])
   self.circuit.rz(angles[1], self.qr[qubit_index])

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

No branches or pull requests

2 participants