def test_adjacency_list(project, check_project): project.add_compilation('hhl', advanced_unitaries.HHL) project['gateset'] = gatesets.QubitCNOTAdjacencyList([(0, 1), (1, 2), (2, 3), (2, 0)]) project.add_compilation('qft3', unitaries.qft(8)) project.run() check_project(project)
def test_reoptimize(project, check_project): target = unitaries.qft(16) project.add_compilation("qft4", target) project["min_depth"] = 4 project["compiler_class"] = leap_compiler.LeapCompiler project.run() project.post_process(post_processing.LEAPReoptimizing_PostProcessor(), reoptimize_size=5) check_project(project)
def test_roundtrip(project): # add some gates 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", gates.qft(16)) #project.add_compilation("full adder", gates.full_adder) #project.add_compilation("ethelyne", advanced_gates.ethelyne) # run the project project.run() # prepare a Qiskit backend to generate unitaries backend = qiskit.BasicAer.get_backend('unitary_simulator') for compilation in project.compilations: # get the original target unitary and final U1 = project.get_target(compilation) # generate and run Qiskit code to create a Qiskit version of the circuit qiskit_code = project.assemble( compilation, assembler=qsearch.assemblers.ASSEMBLER_QISKIT) locals = {} exec(qiskit_code, globals(), locals) qc = locals['qc'] # generate a unitary from the Qiskit circuit job = qiskit.execute(qc, backend) U2 = job.result().get_unitary() U2 = qsearch.utils.endian_reverse( U2) # switch from Qiskit endianess search_compiler endianess distance = qsearch.utils.matrix_distance_squared(U1, U2) # Compare the two unitaries and check the result. The values should be close to 0. assert distance < 1e-13, "Distance for {}: {}".format( compilation, distance)
def test_reoptimize_short(project, check_project): target = unitaries.qft(8) project.add_compilation("qft3", target) project["min_depth"] = 6 project["compiler_class"] = leap_compiler.LeapCompiler project.run() # delete some structure to check it doesn't crash if shorter than reoptimize size project._compilations['qft3'][ 'structure']._subgates = project._compilations['qft3'][ 'structure']._subgates[:3] project.post_process(post_processing.LEAPReoptimizing_PostProcessor(), reoptimize_size=7, timeout=30)
def test_no_grad_gateset(): options = Options() options.target = unitaries.qft(4) options.log_file = None options.gateset = NoJacCNOTLinear() c = compiler.SearchCompiler(options=options) res = c.compile() assert isinstance(c.options.solver, solvers.COBYLA_Solver) assert isinstance(c.options.backend, backends.SmartDefaultBackend) assert isinstance(c.options.backend.prepare_circuit(c.options.gateset.initial_layer(2), c.options), Gate) assert isinstance(c.options.gateset, NoJacCNOTLinear) assert c.options.eval_func is utils.matrix_distance_squared assert c.options.error_func is utils.matrix_distance_squared assert c.options.error_jac is utils.matrix_distance_squared_jac assert c.options.error_residuals is utils.matrix_residuals assert c.options.error_residuals_jac is utils.matrix_residuals_jac
def test_smart_defaults(): options = Options() options.target = unitaries.qft(4) options.log_file=None c = compiler.SearchCompiler(options=options) res = c.compile() if LeastSquares_Jac_SolverNative is not None: assert isinstance(c.options.solver, LeastSquares_Jac_SolverNative) else: assert isinstance(c.options.solver, solvers.LeastSquares_Jac_Solver) assert isinstance(c.options.backend, backends.SmartDefaultBackend) assert not isinstance(c.options.backend.prepare_circuit(c.options.gateset.initial_layer(2), c.options), Gate) assert isinstance(c.options.gateset, gatesets.QubitCNOTLinear) assert c.options.eval_func is utils.matrix_distance_squared assert c.options.error_func is utils.matrix_distance_squared assert c.options.error_jac is utils.matrix_distance_squared_jac assert c.options.error_residuals is utils.matrix_residuals assert c.options.error_residuals_jac is utils.matrix_residuals_jac
def test_leap_simple(project, check_project): project.add_compilation("qft3", unitaries.qft(8)) project["min_depth"] = 6 project["compiler_class"] = leap_compiler.LeapCompiler project.run() check_project(project)
def test_per_compilation_options(project): project['backend'] = backends.SmartDefaultBackend() project.add_compilation('qft3', unitaries.qft(8)) project.run() qft3_opts = project._compilations['qft3']['options'] assert 'backend' not in qft3_opts
def test_project_clear(project): project.add_compilation("qft3", unitaries.qft(8)) project.run() project.clear() project.add_compilation("qft3", unitaries.qft(8)) project.run()
def test_per_compilation_options2(project): opts = Options(backend=backends.PythonBackend()) project.add_compilation('qft3', unitaries.qft(8), options=opts) qft2_opts = project._compilations['qft3']['options'] assert isinstance(qft2_opts.backend, backends.PythonBackend)
backend = qiskit.BasicAer.get_backend('unitary_simulator') # load a qft5 solution qc1 = qiskit.QuantumCircuit.from_qasm_file( f'{os.path.dirname(__file__)}/qft5.qasm') print("Loaded qft5 circuit!") # generate a unitary from the Qiskit circuit job = qiskit.execute(qc1, backend) U2 = job.result().get_unitary() U2 = utils.endian_reverse( U2) # switch from Qiskit endianess qsearch endianess # tell the optimizer what we are solving for opts = Options() opts.verbosity = 1 opts.stdout_enabled = True opts.target = unitaries.qft(32) #qc1.draw(output='mpl') #plt.show() circ, vec = qiskit_to_qsearch(qc1) print( f"Matrix distance of loaded circuit: {utils.matrix_distance_squared(circ.matrix(vec), unitaries.qft(32))}" ) print("Running some circuit verification checks...") circ.validate_structure() compare_gradient(circ) print("Passed checks!") print("Trying to re-optimize the circuit parameters...") for _ in range(100): U1, vec = solv.solve_for_unitary(circ, opts) dist = utils.matrix_distance_squared(U1, unitaries.qft(32))
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
def test_sequential(project): project.add_compilation('qft2', unitaries.qft(4)) project['parallelizer'] = parallelizers.SequentialParallelizer project.run()
from qsearch import Project, parallelizers, unitaries, utils qft3 = unitaries.qft(8) def test_sequential(project): project.add_compilation('qft2', unitaries.qft(4)) project['parallelizer'] = parallelizers.SequentialParallelizer project.run() def test_multiprocessing_parallelizer(project): project.add_compilation('qft3', qft3) project['parallelizer'] = parallelizers.MultiprocessingParallelizer project.run() def test_processpool_parallelizer(project): project.add_compilation('qft3', qft3) project['parallelizer'] = parallelizers.ProcessPoolParallelizer project.run()
def test_rust_solver_qft3(): U = unitaries.qft(8) res = compile(U, LeastSquares_Jac_SolverNative()) circ = res['structure'] v = res['parameters'] assert utils.matrix_distance_squared(U, circ.matrix(v)) < 1e-10
def test_cobyla(project): project.add_compilation('qft2', unitaries.qft(4)) project['solver'] = solvers.COBYLA_Solver() project.run()
from qsearch import ( gates, unitaries, Project, leap_compiler, post_processing, parallelizers, multistart_solvers, gatesets, assemblers, ) if __name__ == '__main__': with Project('qft5-yorktown') as project: # Add a 5 qubit qft project.add_compilation("qft5", unitaries.qft(32)) # configure qsearch to use the LEAP compiler, which scales to more qubits project["compiler_class"] = leap_compiler.LeapCompiler # set a miniumum search depth (to reduce frequent chopping that gets nowhere) project["min_depth"] = 3 # use the IBM yorktown "bowtie" topology project["gateset"] = gatesets.QubitCNOTAdjacencyList([(0, 1), (0, 2), (1, 2), (2, 3), (2, 4), (3, 4)]) # give verbose output to track the synthesis project["verbosity"] = 2 # run synthesis project.run() # LEAP generates sub-optimal results, so we must re-synthesize to get the best results project.post_process( post_processing.LEAPReoptimizing_PostProcessor(),
from qsearch import utils, unitaries, Project, solvers import qsrs import numpy as np qft_py = unitaries.qft(8) qft_rs = qsrs.qft(8) def test_qft(): assert utils.matrix_distance_squared(qft_py, qft_rs) < 1e-14 def test_matrix_distance_squared(): assert qsrs.matrix_distance_squared(qft_py, qft_rs) < 1e-14 def test_matrix_distance_squared_jac(tmpdir): p = Project(str(tmpdir)) p.add_compilation('qft2', qft_py) p.run() res = p.get_result('qft2') c = res['structure'] v = res['parameters'] u, jacs = c.mat_jac(v) f_rs, jacs_rs = qsrs.matrix_distance_squared_jac(qft_py, u, jacs) assert f_rs < 1e-14 f_py, jacs_py = utils.matrix_distance_squared_jac(qft_py, u, jacs) for (j_rs, j_py) in zip(jacs_rs, jacs_py): assert np.allclose(j_rs, j_py), print(j_py) or print(j_rs)