Add the pytest function for MPS in cuquantum.

This commit is contained in:
Liwei Yang
2023-07-24 17:29:29 +08:00
parent a17d8e6b78
commit b043e6a017
3 changed files with 57 additions and 16 deletions

View File

@@ -2,14 +2,15 @@ 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)
self.num_qubits = circ_qibo.nqubits self.num_qubits = circ_qibo.nqubits
self.handle = cutn.create() self.handle = cutn.create()
self.options = {'handle': self.handle} self.options = {'handle': self.handle}
@@ -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)

View File

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

View File

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