From 7554086d6efbd3ecd07c0a65073561df803f3aa1 Mon Sep 17 00:00:00 2001 From: Liwei Yang Date: Fri, 3 Feb 2023 13:50:53 +0800 Subject: [PATCH] Add argparse for parsing args, do clean-up. --- src/qibotn/test_qasm_quimb_backend.py | 140 ++++++++++++++------------ 1 file changed, 77 insertions(+), 63 deletions(-) diff --git a/src/qibotn/test_qasm_quimb_backend.py b/src/qibotn/test_qasm_quimb_backend.py index 2e7e0a2..55447c9 100644 --- a/src/qibotn/test_qasm_quimb_backend.py +++ b/src/qibotn/test_qasm_quimb_backend.py @@ -1,15 +1,15 @@ -import random -from turtle import delay +import argparse import quimb as qu import quimb.tensor as qtn 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 import cirq -nqubits = 18 - # define dictionary gate_dict_cirq = { #'i': I, @@ -67,22 +67,22 @@ def QI_QFT(nqubits: int, with_swaps: bool = True, psi0 = None): return circ def get_gate_params(operation): - if "h" in operation: + if "h " in operation: qbit_no = [int(re.findall(r'\d+', operation)[0])] qbit_no.insert(0, "H") - elif "x" in operation: + elif "x " in operation: qbit_no = [int(re.findall(r'\d+', operation)[0])] qbit_no.insert(0, "X") - elif "y" in operation: + elif "y " in operation: qbit_no = [int(re.findall(r'\d+', operation)[0])] qbit_no.insert(0, "Y") - elif "z" in operation: + elif "z " in operation: qbit_no = [int(re.findall(r'\d+', operation)[0])] qbit_no.insert(0, "Z") - elif "s" in operation: + elif "s " in operation: qbit_no = [int(re.findall(r'\d+', operation)[0])] qbit_no.insert(0, "S") - elif "t" in operation: + elif "t " in operation: qbit_no = [int(re.findall(r'\d+', operation)[0])] qbit_no.insert(0, "T") elif "cu1" in operation: @@ -106,51 +106,63 @@ def get_gate_params(operation): qbit_no = re.findall(r'\d+', operation.split(" ")[1]) qbit_no = [int(x) for x in qbit_no] 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 = [int(x) for x in qbit_no] qbit_no.insert(0, "CX") - elif "cy" in operation: + elif " cy " in operation: qbit_no = re.findall(r'\d+', operation.split(" ")[1]) qbit_no = [int(x) for x in qbit_no] qbit_no.insert(0, "CY") - elif "cz" in operation: + elif " cz " in operation: qbit_no = re.findall(r'\d+', operation.split(" ")[1]) qbit_no = [int(x) for x in qbit_no] 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+)?', operation.split(" ")[0]))) qbit_no = [int(re.findall(r'\d+', operation)[0])] qbit_no[0:0] = ["RX", theta] - elif "ry" in operation: + elif "^ry " in operation: theta = float('.'.join(re.findall(r'\b\d+(?:[Ee][+-]?\d+)?', operation.split(" ")[0]))) qbit_no = [int(re.findall(r'\d+', operation)[0])] qbit_no[0:0] = ["RY", theta] - elif "rz" in operation: + elif "^rz " in operation: theta = float('.'.join(re.findall(r'\b\d+(?:[Ee][+-]?\d+)?', operation.split(" ")[0]))) qbit_no = [int(re.findall(r'\d+', operation)[0])] qbit_no[0:0] = ["RZ", theta] - elif "rzz" in operation: + elif "^rzz " in operation: theta = float('.'.join(re.findall(r'\b\d+(?:[Ee][+-]?\d+)?', operation.split(" ")[0]))) qbit_no = re.findall(r'\d+', operation.split(" ")[1]) qbit_no = [int(x) for x in qbit_no] qbit_no[0:0] = ["RZZ", theta] - elif "u1" in operation: + elif "^u1 " in operation: lamda = float('.'.join(re.findall(r'\b\d+(?:[Ee][+-]?\d+)?', operation.split(" ")[0]))) qbit_no = [int(re.findall(r'\d+', operation)[0])] 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]) phi = float('.'.join(angles[0:2])) lamba = float('.'.join(angles[2:])) qbit_no = int(re.findall(r'\d+', operation)[0]) 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]) theta = float('.'.join(angles[0:2])) phi = float('.'.join(angles[2:4])) @@ -164,28 +176,26 @@ def get_gate_params(operation): def get_gate_functions(qasm_str, start_idx): - # func_list = [] - # param_list = {} - # for line in qasm_str[start_idx:]: - # if "gate" in line: - # line = line.split(" ") - # for i in line[3:]: - # if ',' in i: - # params = i.split(",") - # param_list.append([int(j) for j in params]) - # elif "(" in i: - # params = re.findall(r'\w+', i) - # param_list.append([int(j) for j in params]) - # elif "{" in i: - # break - # elif "}" in line: - # return func_list - # else: - # func_list.append(line) - pass + func_list = [] + param_list = {} + result = [] + idx_inc = 0 + for line in qasm_str[start_idx:]: + if "gate " in line: + result = re.findall("[^,\s()]+", line) + elif result and "{" not in line and "}" not in line: + params = get_gate_params(line) + func_list.append(*params) + elif "}" in line: + print("Returning the list") + print(func_list) + return func_list, idx_incsss + idx_inc += 1 def qasm_QFT(nqubits:int, qasm_str:str, with_swaps: bool = True, psi0 = None): 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) gate_functions = {} 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: break elif "gate" in command: # TODO: Complete gate handling - gate_name = line.split(" ")[1] - # gate_func = get_gate_functions(qasm_str, idx) - # gate_funtions[gate_name] = gate_func + gate_func, increment = get_gate_functions(qasm_str, idx) pass elif "barrier" in command: # TODO: Complete barrier handling pass @@ -218,22 +226,22 @@ def qasm_QFT(nqubits:int, qasm_str:str, with_swaps: bool = True, psi0 = None): 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): # backend (quimb): numpy, cupy, jax. Passed to ``opt_einsum``. # qibo_backend: qibojit, qibotf, tensorflow, numpy # generate random statevector as initial state - init_state = np.random.random(2 ** nqubits) + 1j - * np.random.random(2 ** nqubits) + init_state = 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_quimb = copy.deepcopy(init_state) # Qibo part if compare_qibo==True: - import qibo - qibo.set_backend(qibo_backend) - # qibo.set_backend(backend="qibojit", platform="numba") - from qibo.models import QFT as qibo_qft + # qibo.set_backend(qibo_backend) + # qibo.set_backend(backend=qibo_backend, platform="numba") + qibo.set_backend(backend=qibo_backend, platform="numpy") + start = timer() circ_qibo = qibo_qft(nqubits, with_swaps) 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 - qtn.tensor_core.set_contract_backend(backend) + qu.core.pnjit() ## convert vector to MPS dims = tuple(2*np.ones(nqubits, dtype=int)) start = timer() - init_state_MPS = - qtn.tensor_1d.MatrixProductState.from_dense(init_state, dims) + init_state_MPS = qtn.tensor_1d.MatrixProductState.from_dense(init_state_quimb, dims) end = timer() MPS_time = end-start - # print('MPS conversion time: ', MPS_time) + # construct quimb qft circuit start = timer() - if compare_qibo == True: - circ_quimb = - qasm_QFT(nqubits, qasm_circ, with_swaps, psi0=init_state_MPS) - else: + if compare_qibo == False: 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() end = timer() quimb_qft_time = end-start 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__': - print("Testing for %d nqubits" % (nqubits)) - result = eval_QI_qft(nqubits, compare_qibo=True) \ No newline at end of file + parser = argparse.ArgumentParser() + 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)