qiboteam / qibo

A framework for quantum computing
https://qibo.science
Apache License 2.0
288 stars 60 forks source link

Computing hamiltonians expectation values with the custom backend #413

Closed AdrianPerezSalinas closed 3 years ago

AdrianPerezSalinas commented 3 years ago

hi all,

I am trying to compute the expectation value of some Fermi Hubbard hamiltonian where the terms are of this kind

1.0 [] +
-0.5 [X0 Z1 X2] +
-0.5 [X0 Z1 Z2 Z3 X4] +
-0.5 [Y0 Z1 Y2] +
-0.5 [Y0 Z1 Z2 Z3 Y4] +
-0.25 [Z0] + ...

If I do it with custom backend, I obtain the error message

[Qibo|ERROR|2021-05-20 16:26:50]: Unitary gate supports one or two-qubit gates when using custom operators, but 3 target qubits were given. Please switch to a different backend to execute this operation.

NotImplementedError: Unitary gate supports one or two-qubit gates when using custom operators, but 3 target qubits were given. Please switch to a different backend to execute this operation.

Does it behave as expected? Should we consider implement it for custom backend?

stavros11 commented 3 years ago

Does it behave as expected?

I think yes, because custom operators contain kernels for up to two qubit gates. The trotterization procedure that is coded in qibo just splits the Hamiltonian terms but does not reduce the target qubits of each term, so for example the [Y0 Z1 Y2] will be mapped to a three qubit Unitary gate which cannot be applied using the qibotf backend. It should work with numpy and tensorflow though but ofcourse will be slower.

Should we consider implement it for custom backend?

Regarding implementing this, there are probably two ways:

  1. Reduce the >2 qubit terms to two qubit gates. This can be done exactly since two qubit gate sets are universal but we do not have any compilation algorithm in qibo to do this automatically yet. Also there may be a performance tradeoff between doing it exactly but slow, or approximately but faster that we may want to consider if we try to implement this approach.
  2. Write kernels for >2 qubit gates. The main issue with this solution is that it doesn't scale, for example we can write up to four qubit kernels to accomodate the terms you wrote, but then we won't be able to accomodate a five qubit term, etc.. The reason the custom kernels were up to two qubit is that these are the gates that are more relevant for near-term quantum hardware.
scarrazza commented 3 years ago

@AdrianPerezSalinas could you please measure the execution time for your code using the latest master (0.1.6-dev) with set_backend("numpy") and set_backend("tensorflow")?

AdrianPerezSalinas commented 3 years ago

Hi all, I have got the benchmarks

|   FH model    |  qubits  |      numpy      |   tensorflow    |     qibotf      |
----------------------------------------------------------------------------------
|    (1, 1)     |    2     |    0.000378     |    0.001959     |    0.001718     |
-----------------------------------------------------------------------------------
|    (2, 1)     |    4     |    0.000738     |    0.003472     |    xxxxxxxx     |
-----------------------------------------------------------------------------------
|    (3, 1)     |    6     |    0.001162     |    0.007056     |    xxxxxxxx     |
-----------------------------------------------------------------------------------
|    (4, 1)     |    8     |    0.003196     |    0.019413     |    xxxxxxxx     |
-----------------------------------------------------------------------------------
|    (2, 2)     |    8     |    0.002129     |    0.009549     |    xxxxxxxx     |
-----------------------------------------------------------------------------------
|    (5, 1)     |    10     |    0.028716    |    0.146149     |    xxxxxxxx     |
-----------------------------------------------------------------------------------
|    (6, 1)     |    12     |    0.447142    |    2.827672     |    xxxxxxxx     |
-----------------------------------------------------------------------------------
|    (3, 2)     |    12     |    0.061478    |    0.082026     |    xxxxxxxx     |
-----------------------------------------------------------------------------------
|    (4, 2)     |    16     |    4.307337    |    1.954631     |    xxxxxxxx     |

I do not know why but I could not go beyond 16 qubits, I think it was a memory issue

Errors: Numpy [Qibo|INFO|2021-05-27 12:55:23]: Aborting merge of one and two-qubit terms during TrotterHamiltonian creation because the two-qubit terms are not sufficiently many.

Tensorflow [Qibo|INFO|2021-05-27 12:55:51]: Aborting merge of one and two-qubit terms during TrotterHamiltonian creation because the two-qubit terms are not sufficiently many.

qibotf

[Qibo|ERROR|2021-05-27 12:55:51]: Unitary gate supports one or two-qubit gates when using custom operators, but 3 target qubits were given. Please switch to a different backend to execute this operation.

Traceback (most recent call last):
  File "benchmark_qibo.py", line 41, in <module>
    e = H.expectation(state)#.numpy().real
  File "/home/adrianps/qibo/lib/python3.6/site-packages/qibo-0.1.6.dev0-py3.6.egg/qibo/core/hamiltonians.py", line 559, in expectation
    return Hamiltonian.expectation(self, state, normalize)
  File "/home/adrianps/qibo/lib/python3.6/site-packages/qibo-0.1.6.dev0-py3.6.egg/qibo/core/hamiltonians.py", line 55, in expectation
    ev = state.expectation(self, normalize)
  File "/home/adrianps/qibo/lib/python3.6/site-packages/qibo-0.1.6.dev0-py3.6.egg/qibo/core/states.py", line 120, in expectation
    hstate = hamiltonian @ self.tensor
  File "/home/adrianps/qibo/lib/python3.6/site-packages/qibo-0.1.6.dev0-py3.6.egg/qibo/core/hamiltonians.py", line 572, in __matmul__
    for gate in self.terms():
  File "/home/adrianps/qibo/lib/python3.6/site-packages/qibo-0.1.6.dev0-py3.6.egg/qibo/abstractions/hamiltonians.py", line 470, in terms
    for targets, term in self]
  File "/home/adrianps/qibo/lib/python3.6/site-packages/qibo-0.1.6.dev0-py3.6.egg/qibo/abstractions/hamiltonians.py", line 470, in <listcomp>
    for targets, term in self]
  File "/home/adrianps/qibo/lib/python3.6/site-packages/qibo-0.1.6.dev0-py3.6.egg/qibo/core/gates.py", line 609, in __init__
    "this operation.".format(n))
  File "/home/adrianps/qibo/lib/python3.6/site-packages/qibo-0.1.6.dev0-py3.6.egg/qibo/config.py", line 46, in raise_error
    raise exception(message)
NotImplementedError: Unitary gate supports one or two-qubit gates when using custom operators, but 3 target qubits were given. Please switch to a different backend to execute this operation.
scarrazza commented 3 years ago

@AdrianPerezSalinas thanks for this numbers.

AdrianPerezSalinas commented 3 years ago

I can also upload the .py file for these numbers benchmark_qibo.txt

stavros11 commented 3 years ago

Thanks for the benchmarks.

After some more careful thinking I would like to correct my above post: What I wrote is valid when the Hamiltonian is used for time evolution. In this case we need to apply exp(-i dt H) to the state which after Trotterization will give terms of the form exp(-i dt Y0 Z1 Z2 Z3 Y4) which are indeed four qubit gates and require special kernels.

However, when it comes to expectation values which are the topic of this issue, a four qubit kernel is NOT required. We only need to compute terms like <Psi | Y0 Z1 Z2 Z3 Y4 | Psi > which can be calculated using only one qubit gates. I will have a second look on how the TrotterHamiltonian.expectation method is implemented because I think we can simplify it and make it work with qibotf without the need of additional kernels.

[Qibo|INFO|2021-05-27 12:55:51]: Aborting merge of one and two-qubit terms during TrotterHamiltonian creation because the two-qubit terms are not sufficiently many.

I will also try to check where this comes from because it doesn't sound like a memory issue. There shouldn't be any memory issues with 16 qubits because the TrotterHamiltonian.expectation does not construct any large object other than the state (and perhaps some copies of it) so it should be possible to go up to 24-25 qubits with a decent laptop. It is not like the density matrix which "doubles" the qubits.