NVIDIA / cuda-quantum

C++ and Python support for the CUDA Quantum programming model for heterogeneous quantum-classical workflows
https://nvidia.github.io/cuda-quantum/
Other
423 stars 147 forks source link

State Preparation Circuit Synthesis via Matrix Product State Decomposition #1616

Open 1tnguyen opened 2 months ago

1tnguyen commented 2 months ago

Required prerequisites

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

ACE07-Sev commented 1 month ago

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 commented 1 month ago

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 commented 1 month ago

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 commented 1 month ago

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 commented 1 month ago

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 commented 4 weeks ago

Quick question, can I use quimb in my implementation?

1tnguyen commented 4 weeks ago

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 commented 3 weeks ago

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 commented 3 weeks ago

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 commented 3 weeks ago

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 commented 3 weeks ago

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 commented 3 weeks ago

Oh, and also how to add a U3 gate?

1tnguyen commented 3 weeks ago

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: https://github.com/NVIDIA/cuda-quantum/blob/a423b736e7336b4f7d39b35f69b75c8c20e05fca/python/tests/builder/test_kernel_builder.py#L1352

ACE07-Sev commented 3 weeks ago

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 commented 3 weeks ago

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

ACE07-Sev commented 3 weeks ago

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:

https://github.com/NVIDIA/cuda-quantum/blob/a423b736e7336b4f7d39b35f69b75c8c20e05fca/python/tests/builder/test_kernel_builder.py#L1352

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 commented 3 weeks ago

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])
ACE07-Sev commented 3 weeks ago

I see. I'll try this one out then.

bettinaheim commented 2 weeks ago

FYI, unitary matrix decomposition is also in works (with perf optimizations for simulators). If you use the nightly docker image (nvcr.io/nvidia/nightly/cuda-quantum:latest) you may be able to use it already.

ACE07-Sev commented 2 weeks ago

I see. I'll try to set it up then. It'll definitely help with your 3rd party dependency since it wouldn't need sth like qiskit's transpile. Much appreciate the heads up!

ACE07-Sev commented 2 weeks ago

Ohh, quick question. Does your unitary decomposition (I imagine you're also transpiling?) introduce any global phase?

1tnguyen commented 2 weeks ago

Ohh, quick question. Does your unitary decomposition (I imagine you're also transpiling?) introduce any global phase?

No, the unitary decomposition wouldn't introduce any global phase. btw, we're closing in on the unitaryHACK. If you have some code and want to participate in this year's event, please feel free to post a PR.

ACE07-Sev commented 2 weeks ago

Oh no, I'm not interested in the UnitaryHACK event. I am simply interested in the MPS approach and have been working on it for a few months now, so I'm just eager to contribute this feature to CUDAQ.

ACE07-Sev commented 1 week ago

Greetings there,

Hope you are well. Apologies for the delay, I am currently trying to set up the nightly docker version. I'll notify the moment I get the notebook translated with cudaq.