import qsearch from qsearch import leap_compiler import numpy as np from functools import partial # create the project p = qsearch.Project("stateprep-example") # configure the project with the stateprep defaults instead of the standard synthesis defaults stateprep_options = qsearch.Options( smart_defaults=qsearch.defaults.stateprep_smart_defaults) p.set_smart_defaults(qsearch.defaults.stateprep_smart_defaults) # add states that are converted using generate_stateprep_target_matrix # It may seem strange that we have to pass an identity. Qsearch is still doing unitary synthesis; # stateprep is achieved by modifying the way we compare unitaries such that they are compared by # the state produced by acting on an initial state. # In this case, we are synthesizing a circuit designed to act on the |000> state to match the state # resulting by performing the Identity on the desired state. # Note that you can specify the intiial state for the circuit as initial_state (the default state is # the zero state that matches target_state in number of qudits). toffoli_magic_state = np.array([0.5, 0, 0.5, 0, 0.5, 0, 0, 0.5], dtype='complex128') p.add_compilation("toffoli_magic_state", np.eye(8, dtype='complex128'), target_state=toffoli_magic_state) p.run()
import qsearch from qsearch import unitaries, advanced_unitaries if __name__ == "__main__": # create the project with qsearch.Project("benchmarks") as project: # add a unitaries to compile project.add_compilation("qft2", unitaries.qft(4)) project.add_compilation("qft3", unitaries.qft(8)) project.add_compilation("fredkin", unitaries.fredkin) project.add_compilation("toffoli", unitaries.toffoli) project.add_compilation("peres", unitaries.peres) project.add_compilation("or", unitaries.logical_or) project.add_compilation("miro", advanced_unitaries.mirogate) project.add_compilation("hhl", advanced_unitaries.HHL) # 4 qubit benchmarks (WARNING: These may take days to run.) #project.add_compilation("qft4", unitaries.qft(16)) #project.add_compilation("full adder", unitaries.full_adder) #project.add_compilation("ethylene", advanced_unitaries.ethylene) # compiler configuration example #project["gateset"] = qsearch.gatesets.QubitCNOTRing() # use this to synthesize for the ring topology instead of the default line topology # project["solver"] = qsearch.solver.BFGS_Jac_Solver() # use this to force the compiler to use the BFGS solver instead of using the default setting #project["verbosity"] = 2 # use this to have more information reported to stdout and the log files, or set it to 0 to disable logging altogether # once everything is set up, let the project run! project.run() # once its done you can use the following functions to get output # compilation_names = project.compilations # returns a list of the names that were specified when adding unitaries
import qsearch from qsearch import gatesets, circuits, solvers, multistart_solverss, parallelizers qttof = qsearch.utils.upgrade_dits(qsearch.unitaries.toffoli) p1 = qsearch.Project("qutrit-cpp") p1["solver"] = solvers.BFGS_Jac_Solver() p1["gateset"] = gatesets.QutritCPIPhaseLinear() p1["verbosity"] = 2 p1.add_compilation("csum", circuits.CSUMStep().matrix([])) #p1.add_compilation("toffoli", qttof, depth=8) p1.run() p2 = qsearch.Project("qutrit-cnot") p2["gateset"] = gatesets.QutritCNOTLinear() p2["solver"] = multistart_solverss.MultiStart_Solver(12, "least_squares") p2["parallelizer"] = parallelizers.ProcessPoolParallelizer p2["verbosity"] = 2 p2.add_compilation("csum", circuits.CSUMStep().matrix([])) #p2.add_compilation("toffoli", qttof, depth=8) p2.add_compilation("bswap", qsearch.utils.upgrade_dits(qsearch.unitaries.swap)) p2.add_compilation("tswap", qsearch.unitaries.general_swap(3)) p2.add_compilation("qft2t", qsearch.unitaries.qft(9)) p2.add_compilation("qft3t", qsearch.unitaries.qft(27)) p2.add_compilation("qft3b", qsearch.utils.upgrade_dits(qsearch.unitaries.qft(8))) p2.run()
if len(sys.argv) < 2: print("No QASM file") exit() if len(sys.argv) < 3: output = "output" else: output = sys.argv[2] filename = sys.argv[1] circ = qiskit.QuantumCircuit.from_qasm_file(filename) nq = circ.num_qubits matrix = qiskit.quantum_info.Operator(circ).data if nq < 4: import qsearch qsproj = qsearch.Project(output) qsproj.add_compilation(output, matrix, write_location=(output + "/" + output)) qsproj.run() else: import qfast from os import mkdir try: mkdir(output) except FileExistsError: pass qasm_iteration = 0 def print_potentials(gate_list): global qasm_iteration
def get_new_qasm_from_sc(self): num_hit = 0.0 new_qasm_blocks = [] exe_time = [] if self.syn_tool == 'leap': print("Use LeapCompiler") else: print("Use regular SearchCompiler") project_name = self.project_name for i in range(len(self.unitary_blocks)): start_time = time.time() base = max(0, i - 4 * self.num_q) hit = -1 if hit == -1: u_reversed = sc.utils.endian_reverse(self.unitary_blocks[i]) if not os.path.exists('current_process'): os.mkdir('current_process') np.savetxt('current_process/unitary.txt', self.unitary_blocks[i]) f_cur = open('current_process/status.txt', 'w') f_cur.write(str(self.group_adj[str(self.qubit_mappings[i])])) f_cur.write('\n') f_cur.write('circuit name: %s\n' % self.name) f_cur.write('block idx: %s\n' % i) f_cur.close() f_qasm = open('current_process/circ.qasm', 'w') f_qasm.write(self.qasm_blocks[i]) f_qasm.close() tmp_project_name = 'tmp_%s_%s_%s_%s_%s' % ( self.name, i, str(date.today()), datetime.now().hour, datetime.now().minute) # check if the circuit is generated previously. filename = self.tmp_new_circ + '/new_b_' + str(i) + '.qasm' if os.path.exists(filename): new_circ_file = open(filename, 'r') new_qasm = new_circ_file.read() new_circ_file.close() else: if self.syn_tool == 'sc': project = qsearch.Project(tmp_project_name) project[ "gateset"] = qsearch.gatesets.QubitCNOTAdjacencyList( self.group_adj[str(self.qubit_mappings[i])]) project["threshold"] = self.sc_threshold #project["timeout"] = self.timeout project.add_compilation(self.name, u_reversed) project["verbosity"] = self.verbosity project.run() #project.post_process(post_processing.BasicSingleQubitReduction_PostProcessor(), solver=multistart_solver.MultiStart_Solver(8)) new_qasm = project.assemble(self.name) project.reset() else: project = qsearch.Project(tmp_project_name) project[ "gateset"] = qsearch.gatesets.QubitCNOTAdjacencyList( self.group_adj[str(self.qubit_mappings[i])]) project["threshold"] = self.sc_threshold project.add_compilation(self.name, u_reversed) project["verbosity"] = self.verbosity project["min_depth"] = 6 project["compiler_class"] = leap_compiler.LeapCompiler project.run() phase_1_qasm = project.assemble(self.name) if self.reopt == True and phase_1_qasm.count('cx') > 0: print("resynthesize") reopt_proj_name = '%s_q%s_b%s_%s_%s_%s_reopt' % ( self.name, self.num_q, self.b_size, str(date.today()), datetime.now().hour, datetime.now().minute) with qsearch.Project( reopt_proj_name) as reoptimized: for comp in project.compilations: target = project.get_target(comp) results = project.get_result(comp) circ = results['structure'] cut_depths = results['cut_depths'] best_pair = (circ, results['vector']) reoptimized.add_compilation( comp, target, cut_depths=cut_depths, best_pair=best_pair, depth=5) reoptimized[ 'compiler_class'] = reoptimizing_compiler.ReoptimizingCompiler # Use the multistart solver for better (but slower) results, you may want to # replace 2 with the number of processes you want to give to the optimizer (more processes ~= more accurate) reoptimized[ "solver"] = multistart_solver.MultiStart_Solver( 8) # Multistart requires nested processes, so we use ProcessPoolExecutor reoptimized[ "parallelizer"] = parallelizer.ProcessPoolParallelizer reoptimized['verbosity'] = self.verbosity reoptimized["threshold"] = self.sc_threshold reoptimized[ "gateset"] = qsearch.gatesets.QubitCNOTAdjacencyList( self.group_adj[str( self.qubit_mappings[i])]) reoptimized.run() tmp_qasm = reoptimized.assemble(self.name) if tmp_qasm.count( 'cx') > 0 and self.reopt_single: reoptimized.post_process( post_processing. BasicSingleQubitReduction_PostProcessor( ), solver=multistart_solver. MultiStart_Solver(8)) new_qasm = reoptimized.assemble(self.name) reoptimized.reset() else: new_qasm = phase_1_qasm project.reset() # write new qasm to tmp_new_circ folder out_file = open(filename, 'w') out_file.write(new_qasm) out_file.close() else: print("hit: %s" % (hit)) num_hit += 1 new_qasm = new_qasm_blocks[hit] syn_time = time.time() - start_time new_circ = qk.QuantumCircuit.from_qasm_str(new_qasm) new_circ = transpile(circuits=new_circ, basis_gates=['u3', 'cx'], optimization_level=3) new_qasm = str(new_circ.qasm()).replace("2pi", "2*pi").replace( "3pi", "3*pi").replace("4pi", "4*pi").replace("5pi", "5*pi").replace( "6pi", "6*pi").replace("7pi", "7*pi").replace( "8pi", "8*pi").replace("9pi", "9*pi") new_qasm_blocks.append(new_qasm) exe_time.append(syn_time) print("progress: %s/%s, time: %.2f" % (i, len(self.unitary_blocks), syn_time)) print( "ori cx = %s, new cx = %s" % (self.qasm_blocks[i].count('cx') + 3 * self.qasm_blocks[i].count('swap'), new_qasm.count('cx'))) self.new_qasm_blocks = new_qasm_blocks self.exe_time = exe_time self.hit_rate = num_hit / len(new_qasm_blocks) print("hit rate = %.3f" % (self.hit_rate)) return new_qasm_blocks