chore: Pre-commit all files once more
This commit is contained in:
56
README.md
56
README.md
@@ -5,26 +5,33 @@ To get started, `python setup.py install` to install the tools and dependencies.
|
|||||||
# Supported Computation
|
# Supported Computation
|
||||||
|
|
||||||
Tensor Network Types:
|
Tensor Network Types:
|
||||||
|
|
||||||
- Tensornet (TN)
|
- Tensornet (TN)
|
||||||
- Matrix Product States (MPS)
|
- Matrix Product States (MPS)
|
||||||
|
|
||||||
Tensor Network contractions to:
|
Tensor Network contractions to:
|
||||||
|
|
||||||
- dense vectors
|
- dense vectors
|
||||||
- expecation values of given Pauli string
|
- expecation values of given Pauli string
|
||||||
|
|
||||||
The supported HPC configurations are:
|
The supported HPC configurations are:
|
||||||
|
|
||||||
- single-node CPU
|
- single-node CPU
|
||||||
- single-node GPU or GPUs
|
- single-node GPU or GPUs
|
||||||
- multi-node multi-GPU with Message Passing Interface (MPI)
|
- multi-node multi-GPU with Message Passing Interface (MPI)
|
||||||
- multi-node multi-GPU with NVIDIA Collective Communications Library (NCCL)
|
- multi-node multi-GPU with NVIDIA Collective Communications Library (NCCL)
|
||||||
|
|
||||||
Currently, the supported tensor network libraries are:
|
Currently, the supported tensor network libraries are:
|
||||||
- [cuQuantum](https://github.com/NVIDIA/cuQuantum), an NVIDIA SDK of optimized libraries and tools for accelerating quantum computing workflows.
|
|
||||||
- [quimb](https://quimb.readthedocs.io/en/latest/), an easy but fast python library for ‘quantum information many-body’ calculations, focusing primarily on tensor networks.
|
- [cuQuantum](https://github.com/NVIDIA/cuQuantum), an NVIDIA SDK of optimized libraries and tools for accelerating quantum computing workflows.
|
||||||
|
- [quimb](https://quimb.readthedocs.io/en/latest/), an easy but fast python library for ‘quantum information many-body’ calculations, focusing primarily on tensor networks.
|
||||||
|
|
||||||
# Sample Codes
|
# Sample Codes
|
||||||
|
|
||||||
## Single-Node Example
|
## Single-Node Example
|
||||||
|
|
||||||
The code below shows an example of how to activate the Cuquantum TensorNetwork backend of Qibo.
|
The code below shows an example of how to activate the Cuquantum TensorNetwork backend of Qibo.
|
||||||
|
|
||||||
```py
|
```py
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from qibo import Circuit, gates
|
from qibo import Circuit, gates
|
||||||
@@ -36,20 +43,22 @@ import qibo
|
|||||||
# This will trigger the dense vector computation of the tensornet.
|
# This will trigger the dense vector computation of the tensornet.
|
||||||
|
|
||||||
computation_settings = {
|
computation_settings = {
|
||||||
'MPI_enabled': False,
|
"MPI_enabled": False,
|
||||||
'MPS_enabled': {
|
"MPS_enabled": {
|
||||||
"qr_method": False,
|
"qr_method": False,
|
||||||
"svd_method": {
|
"svd_method": {
|
||||||
"partition": "UV",
|
"partition": "UV",
|
||||||
"abs_cutoff": 1e-12,
|
"abs_cutoff": 1e-12,
|
||||||
},
|
},
|
||||||
} ,
|
},
|
||||||
'NCCL_enabled': False,
|
"NCCL_enabled": False,
|
||||||
'expectation_enabled': False
|
"expectation_enabled": False,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
qibo.set_backend(backend="qibotn", platform="cutensornet", runcard=computation_settings) #cuQuantum
|
qibo.set_backend(
|
||||||
|
backend="qibotn", platform="cutensornet", runcard=computation_settings
|
||||||
|
) # cuQuantum
|
||||||
# qibo.set_backend(backend="qibotn", platform="qutensornet", runcard=computation_settings) #quimb
|
# qibo.set_backend(backend="qibotn", platform="qutensornet", runcard=computation_settings) #quimb
|
||||||
|
|
||||||
|
|
||||||
@@ -70,25 +79,26 @@ Other examples of setting the computation_settings
|
|||||||
```py
|
```py
|
||||||
# Expectation computation with specific Pauli String pattern
|
# Expectation computation with specific Pauli String pattern
|
||||||
computation_settings = {
|
computation_settings = {
|
||||||
'MPI_enabled': False,
|
"MPI_enabled": False,
|
||||||
'MPS_enabled': False,
|
"MPS_enabled": False,
|
||||||
'NCCL_enabled': False,
|
"NCCL_enabled": False,
|
||||||
'expectation_enabled': {
|
"expectation_enabled": {
|
||||||
'pauli_string_pattern': "IXZ"
|
"pauli_string_pattern": "IXZ",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
# Dense vector computation using multi node through MPI
|
# Dense vector computation using multi node through MPI
|
||||||
computation_settings = {
|
computation_settings = {
|
||||||
'MPI_enabled': True,
|
"MPI_enabled": True,
|
||||||
'MPS_enabled': False,
|
"MPS_enabled": False,
|
||||||
'NCCL_enabled': False,
|
"NCCL_enabled": False,
|
||||||
'expectation_enabled': False
|
"expectation_enabled": False,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Multi-Node Example
|
## Multi-Node Example
|
||||||
Multi-node is enabled by setting either the MPI or NCCL enabled flag to True in the computation settings. Below shows the script to launch on 2 nodes with 2 GPUs each. $node_list contains the IP of the nodes assigned.
|
|
||||||
|
|
||||||
|
Multi-node is enabled by setting either the MPI or NCCL enabled flag to True in the computation settings. Below shows the script to launch on 2 nodes with 2 GPUs each. $node_list contains the IP of the nodes assigned.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
mpirun -n 4 -hostfile $node_list python test.py
|
mpirun -n 4 -hostfile $node_list python test.py
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import numpy as np
|
|
||||||
|
|
||||||
from qibo.backends.numpy import NumpyBackend
|
from qibo.backends.numpy import NumpyBackend
|
||||||
from qibo.states import CircuitResult
|
|
||||||
from qibo.config import raise_error
|
from qibo.config import raise_error
|
||||||
|
from qibo.states import CircuitResult
|
||||||
|
|
||||||
|
|
||||||
class QuTensorNet(NumpyBackend):
|
class QuTensorNet(NumpyBackend):
|
||||||
@@ -60,7 +58,6 @@ class QuTensorNet(NumpyBackend):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
xxx.
|
xxx.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import qibotn.eval_qu as eval
|
import qibotn.eval_qu as eval
|
||||||
|
|||||||
@@ -3,9 +3,15 @@ import quimb.tensor as qtn
|
|||||||
from qibo.models import Circuit as QiboCircuit
|
from qibo.models import Circuit as QiboCircuit
|
||||||
|
|
||||||
|
|
||||||
def from_qibo(circuit: QiboCircuit, is_mps: False, psi0=None, method='svd',
|
def from_qibo(
|
||||||
cutoff=1e-6, cutoff_mode='abs'):
|
circuit: QiboCircuit,
|
||||||
"""Create a tensornetwork representation of the circuit"""
|
is_mps: False,
|
||||||
|
psi0=None,
|
||||||
|
method="svd",
|
||||||
|
cutoff=1e-6,
|
||||||
|
cutoff_mode="abs",
|
||||||
|
):
|
||||||
|
"""Create a tensornetwork representation of the circuit."""
|
||||||
|
|
||||||
nqubits = circuit.nqubits
|
nqubits = circuit.nqubits
|
||||||
gate_opt = {}
|
gate_opt = {}
|
||||||
@@ -30,19 +36,17 @@ def from_qibo(circuit: QiboCircuit, is_mps: False, psi0=None, method='svd',
|
|||||||
|
|
||||||
|
|
||||||
def init_state_tn(nqubits, init_state_sv):
|
def init_state_tn(nqubits, init_state_sv):
|
||||||
|
"""Create a matrixproductstate directly from a dense vector."""
|
||||||
"""Create a matrixproductstate directly from a dense vector"""
|
|
||||||
|
|
||||||
dims = tuple(2 * np.ones(nqubits, dtype=int))
|
dims = tuple(2 * np.ones(nqubits, dtype=int))
|
||||||
|
|
||||||
return qtn.tensor_1d.MatrixProductState.from_dense(init_state_sv, dims)
|
return qtn.tensor_1d.MatrixProductState.from_dense(init_state_sv, dims)
|
||||||
|
|
||||||
|
|
||||||
def dense_vector_tn_qu(qasm: str, initial_state, is_mps, backend="numpy"):
|
def dense_vector_tn_qu(qasm: str, initial_state, is_mps, backend="numpy"):
|
||||||
"""Evaluate QASM with Quimb
|
"""Evaluate QASM with Quimb.
|
||||||
|
|
||||||
backend (quimb): numpy, cupy, jax. Passed to ``opt_einsum``.
|
backend (quimb): numpy, cupy, jax. Passed to ``opt_einsum``.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
circuit = QiboCircuit.from_qasm(qasm)
|
circuit = QiboCircuit.from_qasm(qasm)
|
||||||
if initial_state is not None:
|
if initial_state is not None:
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import copy
|
import copy
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import config
|
import config
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pytest
|
import pytest
|
||||||
@@ -8,8 +9,7 @@ from qibo.models import QFT
|
|||||||
|
|
||||||
|
|
||||||
def create_init_state(nqubits):
|
def create_init_state(nqubits):
|
||||||
init_state = np.random.random(2**nqubits) + \
|
init_state = np.random.random(2**nqubits) + 1j * np.random.random(2**nqubits)
|
||||||
1j * np.random.random(2**nqubits)
|
|
||||||
init_state = init_state / np.sqrt((np.abs(init_state) ** 2).sum())
|
init_state = init_state / np.sqrt((np.abs(init_state) ** 2).sum())
|
||||||
return init_state
|
return init_state
|
||||||
|
|
||||||
@@ -20,10 +20,11 @@ def qibo_qft(nqubits, init_state, swaps):
|
|||||||
return circ_qibo, state_vec
|
return circ_qibo, state_vec
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("nqubits, tolerance, is_mps",
|
@pytest.mark.parametrize(
|
||||||
[(1, 1e-6, True), (2, 1e-6, False), (5, 1e-3, True), (10, 1e-3, False)])
|
"nqubits, tolerance, is_mps",
|
||||||
|
[(1, 1e-6, True), (2, 1e-6, False), (5, 1e-3, True), (10, 1e-3, False)],
|
||||||
|
)
|
||||||
def test_eval(nqubits: int, tolerance: float, is_mps: bool):
|
def test_eval(nqubits: int, tolerance: float, is_mps: bool):
|
||||||
|
|
||||||
"""Evaluate circuit with Quimb backend.
|
"""Evaluate circuit with Quimb backend.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -41,20 +42,18 @@ def test_eval(nqubits: int, tolerance: float, is_mps: bool):
|
|||||||
init_state_tn = copy.deepcopy(init_state)
|
init_state_tn = copy.deepcopy(init_state)
|
||||||
|
|
||||||
# Test qibo
|
# Test qibo
|
||||||
qibo.set_backend(backend=config.qibo.backend,
|
qibo.set_backend(backend=config.qibo.backend, platform=config.qibo.platform)
|
||||||
platform=config.qibo.platform)
|
|
||||||
|
qibo_circ, result_sv = qibo_qft(nqubits, init_state, swaps=True)
|
||||||
qibo_circ, result_sv= qibo_qft(nqubits, init_state, swaps=True)
|
|
||||||
|
|
||||||
|
|
||||||
# Convert to qasm for other backends
|
# Convert to qasm for other backends
|
||||||
qasm_circ = qibo_circ.to_qasm()
|
qasm_circ = qibo_circ.to_qasm()
|
||||||
|
|
||||||
# Test quimb
|
# Test quimb
|
||||||
result_tn = qibotn.eval_qu.dense_vector_tn_qu(
|
result_tn = qibotn.eval_qu.dense_vector_tn_qu(
|
||||||
qasm_circ, init_state_tn, is_mps, backend=config.quimb.backend
|
qasm_circ, init_state_tn, is_mps, backend=config.quimb.backend
|
||||||
).flatten()
|
).flatten()
|
||||||
|
|
||||||
|
|
||||||
assert np.allclose(result_sv, result_tn,
|
assert np.allclose(
|
||||||
atol=tolerance), "Resulting dense vectors do not match"
|
result_sv, result_tn, atol=tolerance
|
||||||
|
), "Resulting dense vectors do not match"
|
||||||
|
|||||||
Reference in New Issue
Block a user