Skip to content

Commit

Permalink
Merge branch 'master' into transpiler_refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
changsookim committed Nov 4, 2024
2 parents 0851eeb + 05b57e9 commit ec37f34
Show file tree
Hide file tree
Showing 54 changed files with 2,199 additions and 1,690 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ repos:
- id: isort
args: ["--profile", "black"]
- repo: https://github.com/asottile/pyupgrade
rev: v3.18.0
rev: v3.19.0
hooks:
- id: pyupgrade
- repo: https://github.com/hadialqattan/pycln
Expand Down
29 changes: 29 additions & 0 deletions doc/source/api-reference/qibo.rst
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,11 @@ with the last qubit as the control qubit and the first qubit as a target qubit.
.. autofunction:: qibo.models.encodings.entangling_layer


Greenberger-Horne-Zeilinger (GHZ) state
"""""""""""""""""""""""""""""""""""""""

.. autofunction:: qibo.models.encodings.ghz_state

.. _error-mitigation:

Error Mitigation
Expand Down Expand Up @@ -1826,6 +1831,12 @@ Tsallis entropy
.. autofunction:: qibo.quantum_info.tsallis_entropy


Relative Tsallis entropy
""""""""""""""""""""""""

.. autofunction:: qibo.quantum_info.relative_tsallis_entropy


Entanglement entropy
""""""""""""""""""""

Expand Down Expand Up @@ -1951,6 +1962,12 @@ Frame Potential
.. autofunction:: qibo.quantum_info.frame_potential


Quantum Fisher Information Matrix
"""""""""""""""""""""""""""""""""

.. autofunction:: qibo.quantum_info.quantum_fisher_information_matrix


Linear Algebra Operations
^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -1999,6 +2016,12 @@ Singular value decomposition
.. autofunction:: qibo.quantum_info.singular_value_decomposition


Schmidt decomposition
"""""""""""""""""""""

.. autofunction:: qibo.quantum_info.schmidt_decomposition


Quantum Networks
^^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -2152,6 +2175,12 @@ To Chi
.. autofunction:: qibo.quantum_info.to_chi


To Stinespring
""""""""""""""

.. autofunction:: qibo.quantum_info.to_stinespring


Choi to Liouville
"""""""""""""""""

Expand Down
10 changes: 9 additions & 1 deletion doc/source/appendix/citing-qibo.rst
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@ Peer-Reviewed Articles

.. _`arXiv:2310.05851`: https://arxiv.org/abs/2310.05851

* A. Pasquale, E. Pedicillo, J. Cereijo, S. Ramos-Calderer, A. Candido, G. Palazzo,
R. Carobene, M. Gobbo, S. Efthymiou, Y. Paul Tan, I. Roth, M. Robbiati, J. Wilkens,
A. Orgaz-Fuertes, D. Fuentes-Ruiz, A. Giachero, F. Brito, J. I. Latorre,
*Qibocal: an open-source framework for calibration of self-hosted quantum devices*
(2024), (`arXiv:2410.00101`_)

.. _`arXiv:2410.00101`: https://arxiv.org/abs/2410.00101


Software References in Zenodo
-----------------------------

Expand Down Expand Up @@ -134,7 +143,6 @@ Software References in Zenodo
.. _`https://doi.org/10.5281/zenodo.8083285`: https://doi.org/10.5281/zenodo.8083285



Conference Proceedings
----------------------

Expand Down
68 changes: 45 additions & 23 deletions doc/source/code-examples/advancedexamples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,19 +78,8 @@ or programmatically, during runtime, as follows:
# retrieve the current number of threads
current_threads = qibo.get_threads()

On the other hand, when using the ``tensorflow`` backend Qibo inherits
Tensorflow's defaults for CPU thread configuration.
Tensorflow allows restricting the number of threads as follows:

.. code-block:: python
import tensorflow as tf
tf.config.threading.set_inter_op_parallelism_threads(1)
tf.config.threading.set_intra_op_parallelism_threads(1)
import qibo
Note that this should be run during Tensorflow initialization in the beginning
of the script and before creating the qibo backend.
For similar wariness when using a machine learning backend (such as TensorFlow or Pytorch)
please refer to the Qiboml documentation.

Using multiple GPUs
^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -707,13 +696,18 @@ circuit output matches a target state using the fidelity as the corresponding lo
Note that, as in the following example, the rotation angles have to assume real values
to ensure the rotational gates are representing unitary operators.

Qibo doesn't provide Tensorflow and Pytorch as native backends; Qiboml has to be
installed and used as provider of these quantum machine learning backends.

.. code-block:: python
import qibo
qibo.set_backend("tensorflow")
import tensorflow as tf
qibo.set_backend(backend="qiboml", platform="tensorflow")
from qibo import gates, models
backend = qibo.get_backend()
tf = backend.tf
# Optimization parameters
nepochs = 1000
optimizer = tf.keras.optimizers.Adam()
Expand All @@ -737,8 +731,9 @@ to ensure the rotational gates are representing unitary operators.
optimizer.apply_gradients(zip([grads], [params]))
Note that the ``"tensorflow"`` backend has to be used here because other custom
backends do not support automatic differentiation.
Note that the ``"tensorflow"`` backend has to be used here since it provides
automatic differentiation tools. To be constructed, the Qiboml package has to be
installed and used.

The optimization procedure may also be compiled, however in this case it is not
possible to use :meth:`qibo.circuit.Circuit.set_parameters` as the
Expand All @@ -748,10 +743,12 @@ For example:
.. code-block:: python
import qibo
qibo.set_backend("tensorflow")
import tensorflow as tf
qibo.set_backend(backend="qiboml", platform="tensorflow")
from qibo import gates, models
backend = qibo.get_backend()
tf = backend.tf
nepochs = 1000
optimizer = tf.keras.optimizers.Adam()
target_state = tf.ones(4, dtype=tf.complex128) / 2.0
Expand Down Expand Up @@ -2014,7 +2011,7 @@ to allow calculation of expectation values directly from such samples:
.. testcode::

from qibo import Circuit, gates
from qibo.hamiltonians import Z
from qibo import hamiltonians

circuit = Circuit(4)
circuit.add(gates.H(i) for i in range(4))
Expand All @@ -2023,7 +2020,7 @@ to allow calculation of expectation values directly from such samples:
circuit.add(gates.CNOT(2, 3))
circuit.add(gates.M(*range(4)))
hamiltonian = Z(4)
hamiltonian = hamiltonians.Z(4)

result = circuit(nshots=1024)
expectation_value = hamiltonian.expectation_from_samples(result.frequencies())
Expand All @@ -2038,8 +2035,33 @@ This can also be invoked directly from the ``result`` object:
expectation_value = result.expectation_from_samples(hamiltonian)


The expectation from samples currently works only for Hamiltonians that are diagonal in
the computational basis.
For Hamiltonians that are not diagonal in the computational basis, or that are sum of terms that cannot be
diagonalised simultaneously, one has to calculate the expectation value starting from the circuit:

.. testcode::

from qibo.symbols import X, Y, Z
from qibo.hamiltonians import SymbolicHamiltonian

# build the circuit as before
circuit = Circuit(4)
circuit.add(gates.H(i) for i in range(4))
circuit.add(gates.CNOT(0, 1))
circuit.add(gates.CNOT(1, 2))
circuit.add(gates.CNOT(2, 3))
# but don't add any measurement at the end!
# they will be automatically added with the proper basis
# while calculating the expectation value

hamiltonian = SymbolicHamiltonian(3 * Z(2) * (1 - X(1)) ** 2 - (Y(0) * X(3)) / 2, nqubits=4)
expectation_value = hamiltonian.expectation_from_circuit(circuit)

What is happening under the hood in this case, is that the expectation value is calculated for each term
individually by measuring the circuit in the correct (rotated) basis. All the contributions are then
summed to recover the global expectation value. This means, in particular, that several copies of the
circuit are parallely executed, one for each term of the Hamiltonian. Note that, at the moment, no
check is performed to verify whether a subset of the terms could be diagonalised simultaneously, but
rather each term is treated separately every time.


.. _tutorials_transpiler:
Expand Down
4 changes: 2 additions & 2 deletions examples/anomaly_detection/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf

import qibo
from qibo import Circuit, gates
Expand All @@ -22,7 +21,8 @@ def main(n_layers, train_size, filename, plot, save_loss):
save_loss (bool): save losses for standard and anomalous data (default False).
"""

qibo.set_backend("tensorflow")
qibo.set_backend(backend="qiboml", platform="tensorflow")
tf = qibo.get_backend().tf

# Circuit ansatz
def make_encoder(n_qubits, n_layers, params, q_compression):
Expand Down
4 changes: 2 additions & 2 deletions examples/anomaly_detection/train.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from pathlib import Path

import numpy as np
import tensorflow as tf

import qibo
from qibo import Circuit, gates
Expand All @@ -23,7 +22,8 @@ def main(n_layers, batch_size, nepochs, train_size, filename, lr_boundaries):
lr_boundaries (list): epochs when learning rate is reduced, 6 monotone growing values from 0 to nepochs (default [3,6,9,12,15,18]).
"""

qibo.set_backend("tensorflow")
qibo.set_backend(backend="qiboml", platform="tensorflow")
tf = qibo.get_backend().tf

# Circuit ansatz
def make_encoder(n_qubits, n_layers, params, q_compression):
Expand Down
5 changes: 4 additions & 1 deletion examples/benchmarks/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ def limit_gpu_memory(memory_limit=None):
Args:
memory_limit: Memory limit in MBs.
"""
import tensorflow as tf
import qibo

qibo.set_backend(backend="qiboml", platform="tensorflow")
tf = qibo.get_backend().tf

if memory_limit is None:
print("\nNo GPU memory limiter used.\n")
Expand Down
87 changes: 73 additions & 14 deletions examples/circuit-draw-mpl/qibo-draw-circuit-matplotlib.ipynb

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion examples/qclustering/minimization.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import math

import numpy as np
import tensorflow as tf
from grover import grover_qc
from oracle import create_oracle_circ

import qibo
from qibo import gates
from qibo.models import Circuit

Expand All @@ -23,6 +23,8 @@ def duerr_hoyer_algo(distances):
int
New cluster assigned for that point.
"""
qibo.set_backend(backend="qiboml", platform="tensorflow")
tf = qibo.get_backend().tf

k = len(distances)
n = int(math.floor(math.log2(k)) + 1)
Expand Down
4 changes: 3 additions & 1 deletion examples/reuploading_classifier/qlassifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from matplotlib.cm import get_cmap
from matplotlib.colors import Normalize

import qibo
from qibo import Circuit, gates


Expand Down Expand Up @@ -117,7 +118,8 @@ def minimize(self, method="BFGS", options=None, compile=True):
parameters = r[1].result.xbest

elif method == "sgd":
import tensorflow as tf
qibo.set_backend(backend="qiboml", platform="tensorflow")
tf = qibo.get_backend().tf

circuit = self.circuit(self.training_set[0])

Expand Down
Loading

0 comments on commit ec37f34

Please sign in to comment.