Skip to content

Commit

Permalink
[pre-commit.ci] auto fixes from pre-commit.com hooks
Browse files Browse the repository at this point in the history
for more information, see https://pre-commit.ci
  • Loading branch information
pre-commit-ci[bot] committed Feb 8, 2024
1 parent e6a28ce commit 89e97b4
Show file tree
Hide file tree
Showing 13 changed files with 118 additions and 98 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import qibo

# Below shows how to set the computation_settings
# Note that for MPS_enabled and expectation_enabled parameters the accepted inputs are boolean or a dictionary with the format shown below.
# If computation_settings is not specified, the default setting is used in which all booleans will be False.
# If computation_settings is not specified, the default setting is used in which all booleans will be False.
# This will trigger the dense vector computation of the tensornet.

computation_settings = {
Expand Down Expand Up @@ -92,4 +92,4 @@ Multi-node is enabled by setting either the MPI or NCCL enabled flag to True in

```sh
mpirun -n 4 -hostfile $node_list python test.py
```
```
9 changes: 5 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
from setuptools import setup, find_packages
import re
import pathlib
import re

from setuptools import find_packages, setup

HERE = pathlib.Path(__file__).parent.absolute()
PACKAGE = "qibotn"


# Returns the qibotn version
def version():
"""Gets the version from the package's __init__ file
if there is some problem, let it happily fail"""
"""Gets the version from the package's __init__ file if there is some
problem, let it happily fail."""
version_file = HERE / "src" / PACKAGE / "__init__.py"
version_regex = r"^__version__ = ['\"]([^'\"]*)['\"]"

Expand Down
13 changes: 4 additions & 9 deletions src/qibotn/MPSUtils.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
import cupy as cp
from cuquantum.cutensornet.experimental import contract_decompose
from cuquantum import contract
from cuquantum.cutensornet.experimental import contract_decompose

# Reference: https://github.com/NVIDIA/cuQuantum/blob/main/python/samples/cutensornet/tn_algorithms/mps_algorithms.ipynb


def initial(num_qubits, dtype):
"""
Generate the MPS with an initial state of |00...00>
"""
"""Generate the MPS with an initial state of |00...00>"""
state_tensor = cp.asarray([1, 0], dtype=dtype).reshape(1, 2, 1)
mps_tensors = [state_tensor] * num_qubits
return mps_tensors


def mps_site_right_swap(mps_tensors, i, **kwargs):
"""
Perform the swap operation between the ith and i+1th MPS tensors.
"""
"""Perform the swap operation between the ith and i+1th MPS tensors."""
# contraction followed by QR decomposition
a, _, b = contract_decompose(
"ipj,jqk->iqj,jpk",
Expand All @@ -30,8 +26,7 @@ def mps_site_right_swap(mps_tensors, i, **kwargs):


def apply_gate(mps_tensors, gate, qubits, **kwargs):
"""
Apply the gate operand to the MPS tensors in-place.
"""Apply the gate operand to the MPS tensors in-place.
Args:
mps_tensors: A list of rank-3 ndarray-like tensor objects.
Expand Down
14 changes: 6 additions & 8 deletions src/qibotn/QiboCircuitConvertor.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@


class QiboCircuitToEinsum:
"""Convert a circuit to a Tensor Network (TN) representation.
The circuit is first processed to an intermediate form by grouping each gate
matrix with its corresponding qubit it is acting on to a list. It is then
"""Convert a circuit to a Tensor Network (TN) representation. The circuit
is first processed to an intermediate form by grouping each gate matrix
with its corresponding qubit it is acting on to a list. It is then
converted to an equivalent TN expression through the class function
state_vector_operands() following the Einstein summation convention in the
interleave format.
Expand Down Expand Up @@ -79,9 +79,8 @@ def _parse_gates_to_mode_labels_operands(
return mode_labels, operands

def op_shape_from_qubits(self, nqubits):
"""Modify tensor to cuQuantum shape
(qubit_states,input_output) * qubits_involved
"""
"""Modify tensor to cuQuantum shape (qubit_states,input_output) *
qubits_involved."""
return (2, 2) * nqubits

def init_intermediate_circuit(self, circuit):
Expand Down Expand Up @@ -134,8 +133,7 @@ def init_inverse_circuit(self, circuit):
self.active_qubits_inverse = np.unique(gates_qubits_inverse)

def get_pauli_gates(self, pauli_map, dtype="complex128", backend=cp):
"""
Populate the gates for all pauli operators.
"""Populate the gates for all pauli operators.
Args:
pauli_map: A dictionary mapping qubits to pauli operators.
Expand Down
4 changes: 2 additions & 2 deletions src/qibotn/QiboCircuitToMPS.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import cupy as cp
import numpy as np

from cuquantum import cutensornet as cutn

from qibotn.MPSUtils import apply_gate, initial
from qibotn.QiboCircuitConvertor import QiboCircuitToEinsum
from qibotn.MPSUtils import initial, apply_gate


class QiboCircuitToMPS:
Expand Down
2 changes: 1 addition & 1 deletion src/qibotn/backends/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from qibotn.backends.gpu import CuTensorNet
from qibotn.backends.cpu import QuTensorNet
from qibotn.backends.gpu import CuTensorNet
5 changes: 1 addition & 4 deletions src/qibotn/backends/cpu.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import numpy as np

from qibo.backends.numpy import NumpyBackend
from qibo.states import CircuitResult
from qibo.config import raise_error
from qibo.states import CircuitResult


class QuTensorNet(NumpyBackend):
Expand Down Expand Up @@ -60,7 +58,6 @@ def execute_circuit(
Returns:
xxx.
"""

import qibotn.eval_qu as eval
Expand Down
4 changes: 1 addition & 3 deletions src/qibotn/backends/gpu.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import numpy as np

from qibo.backends.numpy import NumpyBackend
from qibo.states import CircuitResult
from qibo.config import raise_error
from qibo.states import CircuitResult


class CuTensorNet(NumpyBackend): # pragma: no cover
Expand Down Expand Up @@ -107,7 +106,6 @@ def execute_circuit(
Returns:
xxx.
"""

import qibotn.eval as eval
Expand Down
93 changes: 61 additions & 32 deletions src/qibotn/eval.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
from qibotn.QiboCircuitConvertor import QiboCircuitToEinsum
from cuquantum import contract
from cupy.cuda.runtime import getDeviceCount
import cupy as cp
from cupy.cuda.runtime import getDeviceCount
from cuquantum import contract

from qibotn.QiboCircuitToMPS import QiboCircuitToMPS
from qibotn.mps_contraction_helper import MPSContractionHelper
from qibotn.QiboCircuitConvertor import QiboCircuitToEinsum
from qibotn.QiboCircuitToMPS import QiboCircuitToMPS


def dense_vector_tn(qibo_circ, datatype):
"""Convert qibo circuit to tensornet (TN) format and perform contraction to dense vector."""
"""Convert qibo circuit to tensornet (TN) format and perform contraction to
dense vector."""
myconvertor = QiboCircuitToEinsum(qibo_circ, dtype=datatype)
return contract(*myconvertor.state_vector_operands())


def expectation_pauli_tn(qibo_circ, datatype, pauli_string_pattern):
"""Convert qibo circuit to tensornet (TN) format and perform contraction to expectation of given Pauli string."""
"""Convert qibo circuit to tensornet (TN) format and perform contraction to
expectation of given Pauli string."""
myconvertor = QiboCircuitToEinsum(qibo_circ, dtype=datatype)
return contract(
*myconvertor.expectation_operands(
Expand All @@ -24,14 +26,19 @@ def expectation_pauli_tn(qibo_circ, datatype, pauli_string_pattern):


def dense_vector_tn_MPI(qibo_circ, datatype, n_samples=8):
"""Convert qibo circuit to tensornet (TN) format and perform contraction using multi node and multi GPU through MPI.
The conversion is performed by QiboCircuitToEinsum(), after which it goes through 2 steps: pathfinder and execution.
The pathfinder looks at user defined number of samples (n_samples) iteratively to select the least costly contraction path. This is sped up with multi thread.
After pathfinding the optimal path is used in the actual contraction to give a dense vector representation of the TN.
"""Convert qibo circuit to tensornet (TN) format and perform contraction
using multi node and multi GPU through MPI.
The conversion is performed by QiboCircuitToEinsum(), after which it
goes through 2 steps: pathfinder and execution. The pathfinder looks
at user defined number of samples (n_samples) iteratively to select
the least costly contraction path. This is sped up with multi
thread. After pathfinding the optimal path is used in the actual
contraction to give a dense vector representation of the TN.
"""

from mpi4py import MPI
from cuquantum import Network
from mpi4py import MPI

root = 0
comm = MPI.COMM_WORLD
Expand Down Expand Up @@ -86,14 +93,19 @@ def dense_vector_tn_MPI(qibo_circ, datatype, n_samples=8):


def dense_vector_tn_nccl(qibo_circ, datatype, n_samples=8):
"""Convert qibo circuit to tensornet (TN) format and perform contraction using multi node and multi GPU through NCCL.
The conversion is performed by QiboCircuitToEinsum(), after which it goes through 2 steps: pathfinder and execution.
The pathfinder looks at user defined number of samples (n_samples) iteratively to select the least costly contraction path. This is sped up with multi thread.
After pathfinding the optimal path is used in the actual contraction to give a dense vector representation of the TN.
"""Convert qibo circuit to tensornet (TN) format and perform contraction
using multi node and multi GPU through NCCL.
The conversion is performed by QiboCircuitToEinsum(), after which it
goes through 2 steps: pathfinder and execution. The pathfinder looks
at user defined number of samples (n_samples) iteratively to select
the least costly contraction path. This is sped up with multi
thread. After pathfinding the optimal path is used in the actual
contraction to give a dense vector representation of the TN.
"""
from mpi4py import MPI
from cuquantum import Network
from cupy.cuda import nccl
from cuquantum import Network
from mpi4py import MPI

root = 0
comm_mpi = MPI.COMM_WORLD
Expand Down Expand Up @@ -159,15 +171,22 @@ def dense_vector_tn_nccl(qibo_circ, datatype, n_samples=8):


def expectation_pauli_tn_nccl(qibo_circ, datatype, pauli_string_pattern, n_samples=8):
"""Convert qibo circuit to tensornet (TN) format and perform contraction to expectation of given Pauli string using multi node and multi GPU through NCCL.
The conversion is performed by QiboCircuitToEinsum(), after which it goes through 2 steps: pathfinder and execution.
The pauli_string_pattern is used to generate the pauli string corresponding to the number of qubits of the system.
The pathfinder looks at user defined number of samples (n_samples) iteratively to select the least costly contraction path. This is sped up with multi thread.
After pathfinding the optimal path is used in the actual contraction to give an expectation value.
"""Convert qibo circuit to tensornet (TN) format and perform contraction to
expectation of given Pauli string using multi node and multi GPU through
NCCL.
The conversion is performed by QiboCircuitToEinsum(), after which it
goes through 2 steps: pathfinder and execution. The
pauli_string_pattern is used to generate the pauli string
corresponding to the number of qubits of the system. The pathfinder
looks at user defined number of samples (n_samples) iteratively to
select the least costly contraction path. This is sped up with multi
thread. After pathfinding the optimal path is used in the actual
contraction to give an expectation value.
"""
from mpi4py import MPI
from cuquantum import Network
from cupy.cuda import nccl
from cuquantum import Network
from mpi4py import MPI

root = 0
comm_mpi = MPI.COMM_WORLD
Expand Down Expand Up @@ -235,14 +254,21 @@ def expectation_pauli_tn_nccl(qibo_circ, datatype, pauli_string_pattern, n_sampl


def expectation_pauli_tn_MPI(qibo_circ, datatype, pauli_string_pattern, n_samples=8):
"""Convert qibo circuit to tensornet (TN) format and perform contraction to expectation of given Pauli string using multi node and multi GPU through MPI.
The conversion is performed by QiboCircuitToEinsum(), after which it goes through 2 steps: pathfinder and execution.
The pauli_string_pattern is used to generate the pauli string corresponding to the number of qubits of the system.
The pathfinder looks at user defined number of samples (n_samples) iteratively to select the least costly contraction path. This is sped up with multi thread.
After pathfinding the optimal path is used in the actual contraction to give an expectation value.
"""Convert qibo circuit to tensornet (TN) format and perform contraction to
expectation of given Pauli string using multi node and multi GPU through
MPI.
The conversion is performed by QiboCircuitToEinsum(), after which it
goes through 2 steps: pathfinder and execution. The
pauli_string_pattern is used to generate the pauli string
corresponding to the number of qubits of the system. The pathfinder
looks at user defined number of samples (n_samples) iteratively to
select the least costly contraction path. This is sped up with multi
thread. After pathfinding the optimal path is used in the actual
contraction to give an expectation value.
"""
from mpi4py import MPI # this line initializes MPI
from cuquantum import Network
from mpi4py import MPI # this line initializes MPI

root = 0
comm = MPI.COMM_WORLD
Expand Down Expand Up @@ -299,7 +325,8 @@ def expectation_pauli_tn_MPI(qibo_circ, datatype, pauli_string_pattern, n_sample


def dense_vector_mps(qibo_circ, gate_algo, datatype):
"""Convert qibo circuit to matrix product state (MPS) format and perform contraction to dense vector."""
"""Convert qibo circuit to matrix product state (MPS) format and perform
contraction to dense vector."""
myconvertor = QiboCircuitToMPS(qibo_circ, gate_algo, dtype=datatype)
mps_helper = MPSContractionHelper(myconvertor.num_qubits)

Expand All @@ -309,7 +336,9 @@ def dense_vector_mps(qibo_circ, gate_algo, datatype):


def pauli_string_gen(nqubits, pauli_string_pattern):
"""Used internally to generate the string based on given pattern and number of qubit.
"""Used internally to generate the string based on given pattern and number
of qubit.
Example: pattern: "XZ", number of qubit: 7, output = XZXZXZX
"""
if nqubits <= 0:
Expand Down
20 changes: 12 additions & 8 deletions src/qibotn/eval_qu.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@
from qibo.models import Circuit as QiboCircuit


def from_qibo(circuit: QiboCircuit, is_mps: False, psi0=None, method='svd',
cutoff=1e-6, cutoff_mode='abs'):
"""Create a tensornetwork representation of the circuit"""
def from_qibo(
circuit: QiboCircuit,
is_mps: False,
psi0=None,
method="svd",
cutoff=1e-6,
cutoff_mode="abs",
):
"""Create a tensornetwork representation of the circuit."""

nqubits = circuit.nqubits
gate_opt = {}
Expand All @@ -30,19 +36,17 @@ def from_qibo(circuit: QiboCircuit, is_mps: False, psi0=None, method='svd',


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))

return qtn.tensor_1d.MatrixProductState.from_dense(init_state_sv, dims)


def dense_vector_tn_qu(qasm: str, initial_state, is_mps, backend="numpy"):
"""Evaluate QASM with Quimb
def dense_vector_tn_qu(qasm: str, initial_state, is_mps, backend="numpy"):
"""Evaluate QASM with Quimb.
backend (quimb): numpy, cupy, jax. Passed to ``opt_einsum``.
"""
circuit = QiboCircuit.from_qasm(qasm)
if initial_state is not None:
Expand Down
Loading

0 comments on commit 89e97b4

Please sign in to comment.