def benchmark(depth, trail, varying_param): # qasm_file_name = "_private_benchmark/BNTF/16QBT_{:02}CYC_{}_{}.qasm".format( # depth, gdv_name, trail) # # solution_file_name = "_private_benchmark/meta/16QBT_{:02}CYC_{}_{}_solution.csv".format( # depth, gdv_name, trail) if gdv_name == "TFL": folder = "BNTF" depth_string = "{:02}".format(depth) name_end = "TFL" if nr_qubits == 54: name_end = "QSE" elif gdv_name == "QSE": folder = "BSS" depth_string = "{:03}".format(depth) name_end = "QSE" # if nr_qubits==54: # gdv_name = "QSE" qasm_file_name = "_private_benchmark/{}/{}QBT_{}CYC_{}_{}.qasm".format( folder, nr_qubits, depth_string, name_end, trail) solution_file_name = "_private_benchmark/meta/{}QBT_{}CYC_{}_{}_solution.csv".format( nr_qubits, depth_string, name_end, trail) # print("qiskit", depth) # input qasm file as circuit test_circuit = qiskit.QuantumCircuit.from_qasm_file(qasm_file_name) """ Construct the optimal initial mapping """ qiskit_layout_dict = dict() original_nodes = list() with open(solution_file_name, 'r') as csvfile: for original_node in csv.reader(csvfile, delimiter=','): original_nodes.append(literal_eval(original_node[0])) csvfile.close() print(original_nodes) for i in range(len(original_nodes)): qiskit_layout_dict[test_circuit.qregs[0][i]] = original_nodes[i] # construct passes that use the optimal initial mapping and BasicSwap # however, no swapping gates should be ever necessary original_pm = PassManager() # print(original_nodes) qiskit_coupling_map = CouplingMap( couplinglist=connection_list[qubits[nr_qubits]]) optimal_layout = Layout() optimal_layout.from_dict(qiskit_layout_dict) original_pm.append([ SetLayout(optimal_layout), ApplyLayout(), BasicSwap(qiskit_coupling_map) ]) map_original_circuit = original_pm.run(test_circuit) optimal_depth = map_original_circuit.depth() print("optimal mapping: the circuit has", optimal_depth, "cycles") # print(map_original_circuit.draw(style="text")) # construct passes that use the DenseLayout+StochasticSwap without initial mapping """ K7M """ gate_costs = { 'id': 0, 'u1': 0, 'measure': 0, 'reset': 0, 'barrier': 0, 'u2': 1, 'u3': 1, 'U': 1, "ok": 0, # update the costs "rev_cnot": 4 * 1 + 10, # 4 u2/hadamard + 1 cnot "swap": 3 * 10 + 4, # 4 u2/hadamard + 3 cnot 'seed': 19 } # pass the seed through gate costs """ For TFL up to depth 45 20 secunde 4.093154 :: attr_b=5.00,attr_c=0.61,edge_cost=0.20,max_breadth=4,max_depth=9,movement_factor=2 5 secunde 4.138454 :: attr_b=17.30,attr_c=0.25,edge_cost=0.20,max_breadth=3,max_depth=9,movement_factor=4 0.5 secunde 4.322774 :: attr_b=8.00,attr_c=0.02,edge_cost=0.20,max_breadth=2,max_depth=9,movement_factor=2 0.05 secunde 4.464655 :: attr_b=3.50,attr_c=0.31,edge_cost=0.90,max_breadth=2,max_depth=6,movement_factor=6 # Lucian 2.424873 for [-w9 -d9 -b1.50 -c0.32 -e0.80 -m10] """ """ For TFL only up to depth 25 - NISQ scenario 1/100 seconds Timeout la 0005 (a terminat in 1h8m22) Best 4.537083 - pentru -w2 -d3 -b2.00 -c0.74 -e0.20 -m7 Timeout la 0050 (a terminat in 1h48m17) Best 4.278750 - pentru -w2 -d9 -b6.10 -c0.65 -e 1.00 -m6 Timeout la 0500 (a terminat in 2h15m10) Best 3.965833 - pentru -w3 -d9 -b15.70 -c0.91 -e 0.20 -m10 Timeout la 2000 (a terminat in 2h56m23) Best 4.042917 - pentru -w4 -d8 -b6.90 -c0.86 -e 0.20 -m6 """ parameters = { "signature": "25_2000", "att_b": 6.90, "att_c": 0.86, "cx": 0.2, "max_children": 4, "max_depth": 8, "div_dist": 6, # UNUSED "opt_att": True, "opt_max_t_min": False, "qubit_increase_factor": 3, "option_skip_cx": False, "penalty_skip_cx": 20, "opt_div_by_act": False, "TIME_LIMIT": 600 # seconds } parameters_string = str(parameters) # the number of qubits in the device parameters["nisq_qubits"] = qiskit_coupling_map.size() # Add the gate costs parameters["gate_costs"] = gate_costs # Should the initial mapping be chosen random? parameters["initial_map"] = QXXInitialMapping.HEURISTIC parameters["unidirectional_coupling"] = False parameters["dry_run"] = False k7mcomp = QXXCompiler(connection_list[qubits[nr_qubits]], parameters) execution_time = time.time() map_test_circuit, init_time, init_map = k7mcomp.run(test_circuit) execution_time = time.time() - execution_time if (map_test_circuit is None) and (init_map is None): # this happens when the execution was interrupted # Will not write to file of results. So the averages are not affected # by the interrupted experiments return optimal_depth, -1, execution_time, init_time, -1, -1 depth_result = map_test_circuit.depth() print("k7m mapping: the circuit has", depth_result, "cycles") # print(map_test_circuit.draw(style="text")) # accumulate result print("----") file_op_type = "a" global first_run if first_run: file_op_type = "w" first_run = False with open( "_private_data/BNTF/_{}_{}_{}.csv".format(name_end, qubits[nr_qubits], parameters["signature"]), file_op_type) as csvFile: writer = csv.writer(csvFile) writer.writerow( [trail, "k7m", optimal_depth, depth_result, execution_time]) return optimal_depth, depth_result, execution_time, init_time
def benchmark(depth, trail, parameters): if gdv_name == "TFL": folder = "BNTF" depth_string = "{:02}".format(depth) name_end = "TFL" if nr_qubits == 54: name_end = "QSE" elif gdv_name == "QSE": folder = "BSS" depth_string = "{:03}".format(depth) name_end = "QSE" # if nr_qubits==54: # gdv_name = "QSE" qasm_file_name = "_private_benchmark/{}/{}QBT_{}CYC_{}_{}.qasm".format( folder, nr_qubits, depth_string, name_end, trail) solution_file_name = "_private_benchmark/meta/{}QBT_{}CYC_{}_{}_solution.csv".format( nr_qubits, depth_string, name_end, trail) # print("qiskit", depth) # input qasm file as circuit test_circuit = qiskit.QuantumCircuit.from_qasm_file(qasm_file_name) """ Construct the optimal initial mapping """ qiskit_layout_dict = dict() original_nodes = list() with open(solution_file_name, 'r') as csvfile: for original_node in csv.reader(csvfile, delimiter=','): original_nodes.append(literal_eval(original_node[0])) csvfile.close() # print(original_nodes) for i in range(len(original_nodes)): qiskit_layout_dict[test_circuit.qregs[0][i]] = original_nodes[i] # construct passes that use the optimal initial mapping and BasicSwap # however, no swapping gates should be ever necessary original_pm = PassManager() # print(original_nodes) qiskit_coupling_map = CouplingMap( couplinglist=connection_list[qubits[nr_qubits]]) optimal_layout = Layout() optimal_layout.from_dict(qiskit_layout_dict) original_pm.append([ SetLayout(optimal_layout), ApplyLayout(), BasicSwap(qiskit_coupling_map) ]) map_original_circuit = original_pm.run(test_circuit) optimal_depth = map_original_circuit.depth() # print("optimal mapping: the circuit has", optimal_depth, "cycles") # print(map_original_circuit.draw(style="text")) # construct passes that use the DenseLayout+StochasticSwap without initial mapping """ K7M """ gate_costs = { 'id': 0, 'u1': 0, 'measure': 0, 'reset': 0, 'barrier': 0, 'u2': 1, 'u3': 1, 'U': 1, "ok": 0, # update the costs "rev_cnot": 4 * 1 + 10, # 4 u2/hadamard + 1 cnot "swap": 3 * 10 + 4, # 4 u2/hadamard + 3 cnot 'seed': 19 } # pass the seed through gate costs # parameters_string = str(parameters) # the number of qubits in the device parameters["nisq_qubits"] = qiskit_coupling_map.size() # Add the gate costs parameters["gate_costs"] = gate_costs # Should the initial mapping be chosen random? parameters["initial_map"] = QXXInitialMapping.HEURISTIC parameters["unidirectional_coupling"] = False parameters["dry_run"] = False k7mcomp = QXXCompiler(connection_list[qubits[nr_qubits]], parameters) execution_time = time.time() map_test_circuit, init_time, init_map = k7mcomp.run(test_circuit) execution_time = time.time() - execution_time # print(map_test_circuit.draw(output="text", fold=-1)) # tmp_circuit = map_test_circuit.decompose() tmp_circuit = map_test_circuit # print(tmp_circuit.draw(output="text", fold=-1)) # tmp_circuit = qiskit_to_tk(map_test_circuit) # Transform.RebaseToQiskit().DecomposeSWAPtoCX().apply(tmp_circuit) depth_result = tmp_circuit.depth() # print("k7m mapping: the circuit has", depth_result, "cycles") # print(map_test_circuit.draw(style="text")) # accumulate result # print("----") nr_t1 = noOfTranspositions(list(range(nr_qubits)), original_nodes, nr_qubits) nr_t2 = noOfTranspositions(original_nodes, init_map, nr_qubits) return optimal_depth, depth_result, execution_time, init_time, nr_t1, nr_t2
def main(): # Load the circuit circ = QuantumCircuit.from_qasm_file("./circuits/random0_n5_d5.qasm") print(circ.draw(output="text", fold=-1)) # Load the coupling map # name = "./layouts/circle_reg_q5.json" # name = "./layouts/ibmqx3_q16.json" name = "./layouts/rect_def_q20.json" with open(name, 'r') as infile: temp = json.load(infile) coupling = [] for ii, kk in temp["coupling_map"].items(): for k in kk: coupling += [[int(ii), k]] """ K7M """ gate_costs = {'id': 0, 'u1': 0, 'measure': 0, 'reset': 0, 'barrier': 0, 'u2': 1, 'u3': 1, 'U': 1, 'cx': 10, 'CX': 10, "rev_cx_edge" : 10, # related to the edge in the coupling "ok": 0, # update the costs "rev_cnot": 4 * 1 + 10, # 4 u2/hadamard + 1 cnot "swap": 3 * 10 + 4, # 4 u2/hadamard + 3 cnot 'seed': 19} # pass the seed through gate costs parameters = { # maximum depth of the search tree # after this depth, the leafs are evaluated # and only the path with minimum cost is kept in the tree # thus, the tree is pruned "max_depth": circ.n_qubits, # "max_depth": test_circuit.n_qubits/4, # maximum number of children of a node # "max_children": qiskit_coupling_map.size(), "max_children": 3, # the first number_of_qubits * this factor the search maximises the cost # afterwards it minimises it "opt_max_t_min": False, "qubit_increase_factor": 3, "option_skip_cx": False, "penalty_skip_cx": 20, "opt_div_by_act": True, # later changes in the mapping should not affect # the initial mapping of the circuit "opt_att": True, # b \in [0, 10] "att_b": 0, # c \in [0, 1] "att_c": 1, } parameters_string = str(parameters) # the number of qubits in the device parameters["nisq_qubits"] = temp["qubits"] # Add the gate costs parameters["gate_costs"] = gate_costs # Should the initial mapping be chosen random? parameters["initial_map"] = QXXInitialMapping.HEURISTIC parameters["unidirectional_coupling"] = False parameters["dry_run"] = False k7m = QXXCompiler(coupling, parameters) result = k7m.run(circ) print(result.draw(output="text", fold=-1, idle_wires=False))