Add argparse for parsing args, do clean-up.

This commit is contained in:
Liwei Yang
2023-02-03 13:50:53 +08:00
parent 2fb08c51ed
commit 7554086d6e

View File

@@ -1,15 +1,15 @@
import random import argparse
from turtle import delay
import quimb as qu import quimb as qu
import quimb.tensor as qtn import quimb.tensor as qtn
import numpy as np import numpy as np
import re import re, copy
import qibo
from qibo.models import QFT as qibo_qft
from timeit import default_timer as timer from timeit import default_timer as timer
import cirq import cirq
nqubits = 18
# define dictionary # define dictionary
gate_dict_cirq = { gate_dict_cirq = {
#'i': I, #'i': I,
@@ -67,22 +67,22 @@ def QI_QFT(nqubits: int, with_swaps: bool = True, psi0 = None):
return circ return circ
def get_gate_params(operation): def get_gate_params(operation):
if "h" in operation: if "h " in operation:
qbit_no = [int(re.findall(r'\d+', operation)[0])] qbit_no = [int(re.findall(r'\d+', operation)[0])]
qbit_no.insert(0, "H") qbit_no.insert(0, "H")
elif "x" in operation: elif "x " in operation:
qbit_no = [int(re.findall(r'\d+', operation)[0])] qbit_no = [int(re.findall(r'\d+', operation)[0])]
qbit_no.insert(0, "X") qbit_no.insert(0, "X")
elif "y" in operation: elif "y " in operation:
qbit_no = [int(re.findall(r'\d+', operation)[0])] qbit_no = [int(re.findall(r'\d+', operation)[0])]
qbit_no.insert(0, "Y") qbit_no.insert(0, "Y")
elif "z" in operation: elif "z " in operation:
qbit_no = [int(re.findall(r'\d+', operation)[0])] qbit_no = [int(re.findall(r'\d+', operation)[0])]
qbit_no.insert(0, "Z") qbit_no.insert(0, "Z")
elif "s" in operation: elif "s " in operation:
qbit_no = [int(re.findall(r'\d+', operation)[0])] qbit_no = [int(re.findall(r'\d+', operation)[0])]
qbit_no.insert(0, "S") qbit_no.insert(0, "S")
elif "t" in operation: elif "t " in operation:
qbit_no = [int(re.findall(r'\d+', operation)[0])] qbit_no = [int(re.findall(r'\d+', operation)[0])]
qbit_no.insert(0, "T") qbit_no.insert(0, "T")
elif "cu1" in operation: elif "cu1" in operation:
@@ -106,51 +106,63 @@ def get_gate_params(operation):
qbit_no = re.findall(r'\d+', operation.split(" ")[1]) qbit_no = re.findall(r'\d+', operation.split(" ")[1])
qbit_no = [int(x) for x in qbit_no] qbit_no = [int(x) for x in qbit_no]
qbit_no[0:0] = ["CU3", theta, phi, lamda] qbit_no[0:0] = ["CU3", theta, phi, lamda]
elif "cx" in operation: elif " cx " in operation:
qbit_no = re.findall(r'\d+', operation.split(" ")[1]) qbit_no = re.findall(r'\d+', operation.split(" ")[1])
qbit_no = [int(x) for x in qbit_no] qbit_no = [int(x) for x in qbit_no]
qbit_no.insert(0, "CX") qbit_no.insert(0, "CX")
elif "cy" in operation: elif " cy " in operation:
qbit_no = re.findall(r'\d+', operation.split(" ")[1]) qbit_no = re.findall(r'\d+', operation.split(" ")[1])
qbit_no = [int(x) for x in qbit_no] qbit_no = [int(x) for x in qbit_no]
qbit_no.insert(0, "CY") qbit_no.insert(0, "CY")
elif "cz" in operation: elif " cz " in operation:
qbit_no = re.findall(r'\d+', operation.split(" ")[1]) qbit_no = re.findall(r'\d+', operation.split(" ")[1])
qbit_no = [int(x) for x in qbit_no] qbit_no = [int(x) for x in qbit_no]
qbit_no.insert(0, "CZ") qbit_no.insert(0, "CZ")
elif "rx" in operation: elif " ccx " in operation:
qbit_no = re.findall(r'\d+', operation.split(" ")[1])
qbit_no = [int(x) for x in qbit_no]
qbit_no.insert(0, "CCX")
elif " ccy " in operation:
qbit_no = re.findall(r'\d+', operation.split(" ")[1])
qbit_no = [int(x) for x in qbit_no]
qbit_no.insert(0, "CCY")
elif " ccz " in operation:
qbit_no = re.findall(r'\d+', operation.split(" ")[1])
qbit_no = [int(x) for x in qbit_no]
qbit_no.insert(0, "CCZ")
elif " rx " in operation:
theta = float('.'.join(re.findall(r'\b\d+(?:[Ee][+-]?\d+)?', theta = float('.'.join(re.findall(r'\b\d+(?:[Ee][+-]?\d+)?',
operation.split(" ")[0]))) operation.split(" ")[0])))
qbit_no = [int(re.findall(r'\d+', operation)[0])] qbit_no = [int(re.findall(r'\d+', operation)[0])]
qbit_no[0:0] = ["RX", theta] qbit_no[0:0] = ["RX", theta]
elif "ry" in operation: elif "^ry " in operation:
theta = float('.'.join(re.findall(r'\b\d+(?:[Ee][+-]?\d+)?', theta = float('.'.join(re.findall(r'\b\d+(?:[Ee][+-]?\d+)?',
operation.split(" ")[0]))) operation.split(" ")[0])))
qbit_no = [int(re.findall(r'\d+', operation)[0])] qbit_no = [int(re.findall(r'\d+', operation)[0])]
qbit_no[0:0] = ["RY", theta] qbit_no[0:0] = ["RY", theta]
elif "rz" in operation: elif "^rz " in operation:
theta = float('.'.join(re.findall(r'\b\d+(?:[Ee][+-]?\d+)?', theta = float('.'.join(re.findall(r'\b\d+(?:[Ee][+-]?\d+)?',
operation.split(" ")[0]))) operation.split(" ")[0])))
qbit_no = [int(re.findall(r'\d+', operation)[0])] qbit_no = [int(re.findall(r'\d+', operation)[0])]
qbit_no[0:0] = ["RZ", theta] qbit_no[0:0] = ["RZ", theta]
elif "rzz" in operation: elif "^rzz " in operation:
theta = float('.'.join(re.findall(r'\b\d+(?:[Ee][+-]?\d+)?', theta = float('.'.join(re.findall(r'\b\d+(?:[Ee][+-]?\d+)?',
operation.split(" ")[0]))) operation.split(" ")[0])))
qbit_no = re.findall(r'\d+', operation.split(" ")[1]) qbit_no = re.findall(r'\d+', operation.split(" ")[1])
qbit_no = [int(x) for x in qbit_no] qbit_no = [int(x) for x in qbit_no]
qbit_no[0:0] = ["RZZ", theta] qbit_no[0:0] = ["RZZ", theta]
elif "u1" in operation: elif "^u1 " in operation:
lamda = float('.'.join(re.findall(r'\b\d+(?:[Ee][+-]?\d+)?', lamda = float('.'.join(re.findall(r'\b\d+(?:[Ee][+-]?\d+)?',
operation.split(" ")[0]))) operation.split(" ")[0])))
qbit_no = [int(re.findall(r'\d+', operation)[0])] qbit_no = [int(re.findall(r'\d+', operation)[0])]
qbit_no[0:0] = ["U1", lamda] qbit_no[0:0] = ["U1", lamda]
elif "u2" in operation: elif "^u2 " in operation:
angles = re.findall(r'\b\d+(?:[Ee][+-]?\d+)?',operation.split(" ")[0]) angles = re.findall(r'\b\d+(?:[Ee][+-]?\d+)?',operation.split(" ")[0])
phi = float('.'.join(angles[0:2])) phi = float('.'.join(angles[0:2]))
lamba = float('.'.join(angles[2:])) lamba = float('.'.join(angles[2:]))
qbit_no = int(re.findall(r'\d+', operation)[0]) qbit_no = int(re.findall(r'\d+', operation)[0])
qbit_no[0:0] = ["U2", phi, lamda] qbit_no[0:0] = ["U2", phi, lamda]
elif "u3" in operation: elif "^u3 " in operation:
angles = re.findall(r'\b\d+(?:[Ee][+-]?\d+)?',operation.split(" ")[0]) angles = re.findall(r'\b\d+(?:[Ee][+-]?\d+)?',operation.split(" ")[0])
theta = float('.'.join(angles[0:2])) theta = float('.'.join(angles[0:2]))
phi = float('.'.join(angles[2:4])) phi = float('.'.join(angles[2:4]))
@@ -164,28 +176,26 @@ def get_gate_params(operation):
def get_gate_functions(qasm_str, start_idx): def get_gate_functions(qasm_str, start_idx):
# func_list = [] func_list = []
# param_list = {} param_list = {}
# for line in qasm_str[start_idx:]: result = []
# if "gate" in line: idx_inc = 0
# line = line.split(" ") for line in qasm_str[start_idx:]:
# for i in line[3:]: if "gate " in line:
# if ',' in i: result = re.findall("[^,\s()]+", line)
# params = i.split(",") elif result and "{" not in line and "}" not in line:
# param_list.append([int(j) for j in params]) params = get_gate_params(line)
# elif "(" in i: func_list.append(*params)
# params = re.findall(r'\w+', i) elif "}" in line:
# param_list.append([int(j) for j in params]) print("Returning the list")
# elif "{" in i: print(func_list)
# break return func_list, idx_incsss
# elif "}" in line: idx_inc += 1
# return func_list
# else:
# func_list.append(line)
pass
def qasm_QFT(nqubits:int, qasm_str:str, with_swaps: bool = True, psi0 = None): def qasm_QFT(nqubits:int, qasm_str:str, with_swaps: bool = True, psi0 = None):
circ = qtn.Circuit(nqubits, psi0 = psi0) circ = qtn.Circuit(nqubits, psi0 = psi0)
# circ.psi.draw(color=['PSI0','CU1', 'H', 'SWAP'], show_inds=None, show_tags=False,font_size=40, font_size_inner=20)
# circ = qtn.Circuit.qasm(nqubits, psi0 = psi0) # circ = qtn.Circuit.qasm(nqubits, psi0 = psi0)
gate_functions = {} gate_functions = {}
qasm_str = qasm_str.split('\n') qasm_str = qasm_str.split('\n')
@@ -199,9 +209,7 @@ def qasm_QFT(nqubits:int, qasm_str:str, with_swaps: bool = True, psi0 = None):
elif "swap" in command: elif "swap" in command:
break break
elif "gate" in command: # TODO: Complete gate handling elif "gate" in command: # TODO: Complete gate handling
gate_name = line.split(" ")[1] gate_func, increment = get_gate_functions(qasm_str, idx)
# gate_func = get_gate_functions(qasm_str, idx)
# gate_funtions[gate_name] = gate_func
pass pass
elif "barrier" in command: # TODO: Complete barrier handling elif "barrier" in command: # TODO: Complete barrier handling
pass pass
@@ -218,22 +226,22 @@ def qasm_QFT(nqubits:int, qasm_str:str, with_swaps: bool = True, psi0 = None):
return circ return circ
def eval_QI_qft(nqubits, bond_dim=0, backend='numpy', qibo_backend='numpy', def eval_QI_qft(nqubits, bond_dim=0, backend='numpy', qibo_backend='qibojit',
with_swaps=True, compare_qibo=False): with_swaps=True, compare_qibo=False):
# backend (quimb): numpy, cupy, jax. Passed to ``opt_einsum``. # backend (quimb): numpy, cupy, jax. Passed to ``opt_einsum``.
# qibo_backend: qibojit, qibotf, tensorflow, numpy # qibo_backend: qibojit, qibotf, tensorflow, numpy
# generate random statevector as initial state # generate random statevector as initial state
init_state = np.random.random(2 ** nqubits) + 1j init_state = np.random.random(2 ** nqubits) + 1j * np.random.random(2 ** nqubits)
* 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())
init_state_quimb = copy.deepcopy(init_state)
# Qibo part # Qibo part
if compare_qibo==True: if compare_qibo==True:
import qibo # qibo.set_backend(qibo_backend)
qibo.set_backend(qibo_backend) # qibo.set_backend(backend=qibo_backend, platform="numba")
# qibo.set_backend(backend="qibojit", platform="numba") qibo.set_backend(backend=qibo_backend, platform="numpy")
from qibo.models import QFT as qibo_qft
start = timer() start = timer()
circ_qibo = qibo_qft(nqubits, with_swaps) circ_qibo = qibo_qft(nqubits, with_swaps)
amplitudes_reference = np.array(circ_qibo(init_state)) amplitudes_reference = np.array(circ_qibo(init_state))
@@ -243,33 +251,39 @@ def eval_QI_qft(nqubits, bond_dim=0, backend='numpy', qibo_backend='numpy',
##################################################################### #####################################################################
# Quimb part # Quimb part
qtn.tensor_core.set_contract_backend(backend) qu.core.pnjit()
## convert vector to MPS ## convert vector to MPS
dims = tuple(2*np.ones(nqubits, dtype=int)) dims = tuple(2*np.ones(nqubits, dtype=int))
start = timer() start = timer()
init_state_MPS = init_state_MPS = qtn.tensor_1d.MatrixProductState.from_dense(init_state_quimb, dims)
qtn.tensor_1d.MatrixProductState.from_dense(init_state, dims)
end = timer() end = timer()
MPS_time = end-start MPS_time = end-start
# print('MPS conversion time: ', MPS_time)
# construct quimb qft circuit # construct quimb qft circuit
start = timer() start = timer()
if compare_qibo == True: if compare_qibo == False:
circ_quimb =
qasm_QFT(nqubits, qasm_circ, with_swaps, psi0=init_state_MPS)
else:
circ_quimb = QI_QFT(nqubits, with_swaps, psi0=init_state_MPS) circ_quimb = QI_QFT(nqubits, with_swaps, psi0=init_state_MPS)
else:
circ_quimb = qasm_QFT(nqubits, qasm_circ, with_swaps, psi0=init_state_MPS)
interim = circ_quimb.psi.full_simplify(seq="DRC")
result = interim.to_dense(backend=backend)
result = circ_quimb.to_dense(backend=backend)
amplitudes = result.flatten() amplitudes = result.flatten()
end = timer() end = timer()
quimb_qft_time = end-start quimb_qft_time = end-start
print("quimb time is " + str(quimb_qft_time)) print("quimb time is " + str(quimb_qft_time))
assert(np.allclose(amplitudes,amplitudes_reference)) assert(np.allclose(amplitudes,amplitudes_reference,atol=1e-06))
if __name__ == '__main__': if __name__ == '__main__':
print("Testing for %d nqubits" % (nqubits)) parser = argparse.ArgumentParser()
result = eval_QI_qft(nqubits, compare_qibo=True) parser.add_argument("--nqubits", default=10, type=int,
help="Number of quibits in the circuits.")
args = parser.parse_args()
print("Testing for %d nqubits" % (args.nqubits))
result = eval_QI_qft(args.nqubits, compare_qibo=True)