Add the pytest function for MPS in cuquantum.
This commit is contained in:
@@ -2,11 +2,12 @@ import cupy as cp
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from cuquantum import cutensornet as cutn
|
from cuquantum import cutensornet as cutn
|
||||||
from QiboCircuitConvertor import QiboCircuitToEinsum
|
from qibotn.QiboCircuitConvertor import QiboCircuitToEinsum
|
||||||
from MPSUtils import get_initial_mps, apply_gate
|
from qibotn.MPSUtils import get_initial_mps, apply_gate
|
||||||
|
|
||||||
|
|
||||||
class QiboCircuitToMPS:
|
class QiboCircuitToMPS:
|
||||||
def __init__(self,circ_qibo, gate_algo, dtype = 'complex128',rand_seed=0,):
|
def __init__(self, circ_qibo, gate_algo, dtype='complex128', rand_seed=0,):
|
||||||
np.random.seed(rand_seed)
|
np.random.seed(rand_seed)
|
||||||
cp.random.seed(rand_seed)
|
cp.random.seed(rand_seed)
|
||||||
|
|
||||||
@@ -20,7 +21,8 @@ class QiboCircuitToMPS:
|
|||||||
for (gate, qubits) in circuitconvertor.gate_tensors:
|
for (gate, qubits) in circuitconvertor.gate_tensors:
|
||||||
# mapping from qubits to qubit indices
|
# mapping from qubits to qubit indices
|
||||||
# apply the gate in-place
|
# apply the gate in-place
|
||||||
apply_gate(self.mps_tensors, gate, qubits, algorithm=gate_algo, options=self.options)
|
apply_gate(self.mps_tensors, gate, qubits,
|
||||||
|
algorithm=gate_algo, options=self.options)
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
cutn.destroy(self.handle)
|
cutn.destroy(self.handle)
|
||||||
|
|||||||
@@ -1,33 +1,34 @@
|
|||||||
from qibotn.QiboCircuitConvertor import QiboCircuitToEinsum
|
from qibotn.QiboCircuitConvertor import QiboCircuitToEinsum
|
||||||
from cuquantum import contract
|
from cuquantum import contract
|
||||||
from MpsHelper import MPSHelper
|
|
||||||
import cuquantum
|
|
||||||
from cuquantum import cutensornet as cutn
|
from cuquantum import cutensornet as cutn
|
||||||
import cupy as cp
|
import cupy as cp
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from qibo.models import QFT
|
from qibo.models import QFT
|
||||||
from QiboCircuitToMPS import QiboCircuitToMPS
|
from qibotn.QiboCircuitToMPS import QiboCircuitToMPS
|
||||||
from MPSContractionHelper import MPSContractionHelper
|
from qibotn.MPSContractionHelper import MPSContractionHelper
|
||||||
|
|
||||||
|
|
||||||
def eval(qibo_circ, datatype):
|
def eval(qibo_circ, datatype):
|
||||||
myconvertor = QiboCircuitToEinsum(qibo_circ, dtype=datatype)
|
myconvertor = QiboCircuitToEinsum(qibo_circ, dtype=datatype)
|
||||||
return contract(*myconvertor.state_vector_operands())
|
return contract(*myconvertor.state_vector_operands())
|
||||||
|
|
||||||
|
|
||||||
def eval_mps(qibo_circ, gate_algo, datatype):
|
def eval_mps(qibo_circ, gate_algo, datatype):
|
||||||
myconvertor = QiboCircuitToMPS(qibo_circ, gate_algo, datatype)
|
myconvertor = QiboCircuitToMPS(qibo_circ, gate_algo, dtype=datatype)
|
||||||
mps_helper = MPSContractionHelper(myconvertor.num_qubits)
|
mps_helper = MPSContractionHelper(myconvertor.num_qubits)
|
||||||
sv_mps = mps_helper.contract_state_vector(myconvertor.mps_tensors,myconvertor.options)
|
sv_mps = mps_helper.contract_state_vector(
|
||||||
|
myconvertor.mps_tensors, myconvertor.options)
|
||||||
return sv_mps
|
return sv_mps
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
num_qubits = 25
|
num_qubits = 25
|
||||||
swaps = True
|
swaps = True
|
||||||
circ_qibo = QFT(num_qubits, swaps)
|
circ_qibo = QFT(num_qubits, swaps)
|
||||||
|
|
||||||
exact_gate_algorithm = {'qr_method': False,
|
exact_gate_algorithm = {'qr_method': False,
|
||||||
'svd_method':{'partition': 'UV', 'abs_cutoff':1e-12}}
|
'svd_method': {'partition': 'UV', 'abs_cutoff': 1e-12}}
|
||||||
dtype="complex128"
|
dtype = "complex128"
|
||||||
sv_mps = eval_mps(circ_qibo, exact_gate_algorithm, dtype)
|
sv_mps = eval_mps(circ_qibo, exact_gate_algorithm, dtype)
|
||||||
sv_reference = eval(circ_qibo, dtype)
|
sv_reference = eval(circ_qibo, dtype)
|
||||||
state_vec = np.array(circ_qibo())
|
state_vec = np.array(circ_qibo())
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ from timeit import default_timer as timer
|
|||||||
|
|
||||||
import config
|
import config
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
import cupy as cp
|
||||||
import pytest
|
import pytest
|
||||||
import qibo
|
import qibo
|
||||||
from qibo.models import QFT
|
from qibo.models import QFT
|
||||||
@@ -46,3 +47,40 @@ def test_eval(nqubits: int, dtype="complex128"):
|
|||||||
assert 1e-2 * qibo_time < cutn_time < 1e2 * qibo_time
|
assert 1e-2 * qibo_time < cutn_time < 1e2 * qibo_time
|
||||||
assert np.allclose(
|
assert np.allclose(
|
||||||
result_sv, result_tn), "Resulting dense vectors do not match"
|
result_sv, result_tn), "Resulting dense vectors do not match"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.gpu
|
||||||
|
@pytest.mark.parametrize("nqubits", [2, 5, 10])
|
||||||
|
def test_mps(nqubits: int, dtype="complex128"):
|
||||||
|
"""Evaluate MPS with cuQuantum.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
nqubits (int): Total number of qubits in the system.
|
||||||
|
dtype (str): The data type for precision, 'complex64' for single,
|
||||||
|
'complex128' for double.
|
||||||
|
"""
|
||||||
|
import qibotn.cutn
|
||||||
|
|
||||||
|
# Test qibo
|
||||||
|
qibo.set_backend(backend=config.qibo.backend,
|
||||||
|
platform=config.qibo.platform)
|
||||||
|
|
||||||
|
qibo_time, (circ_qibo, result_sv) = time(
|
||||||
|
lambda: qibo_qft(nqubits, swaps=True))
|
||||||
|
|
||||||
|
result_sv_cp = cp.asarray(result_sv)
|
||||||
|
|
||||||
|
# Test of MPS
|
||||||
|
gate_algo = {'qr_method': False,
|
||||||
|
'svd_method': {
|
||||||
|
'partition': 'UV',
|
||||||
|
'abs_cutoff': 1e-12,
|
||||||
|
}}
|
||||||
|
|
||||||
|
cutn_time, result_tn = time(
|
||||||
|
lambda: qibotn.cutn.eval_mps(circ_qibo, gate_algo, dtype).flatten())
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"State vector difference: {abs(result_tn - result_sv_cp).max():0.3e}")
|
||||||
|
|
||||||
|
assert cp.allclose(result_tn, result_sv_cp)
|
||||||
|
|||||||
Reference in New Issue
Block a user