コード例 #1
0
def run(d, fname):
    
    f = open(fname, "w")
        
    f.write("name,Orig. total,Orig. CNOT,Orig. T,PyZX total,PyZX CNOT,PyZX T,time\n")
    
    for fname in os.listdir(d):

        print("Processing %s..." % fname)
        
        circ = zx.Circuit.load(os.path.join(d, fname)).to_basic_gates()
        num_gates_before = len(circ.gates)
        cnot_count_before = circ.twoqubitcount()
        t_count_before = zx.tcount(circ)
        print("Original:\t Total %d, CNOT %d, T %d" % (num_gates_before, cnot_count_before, t_count_before))
        
        start = time.perf_counter() # start timer
        g = circ.to_graph()
        zx.full_reduce(g,quiet=False)
        g.normalize()
        new_circ = zx.extract_circuit(g).to_basic_gates()
        stop = time.perf_counter() # stop timer
        num_gates_after = len(new_circ.gates)
        cnot_count_after = new_circ.twoqubitcount()
        t_count_after = zx.tcount(new_circ)
        print("Final:\t Total %d, CNOT %d, T %d\n" % (num_gates_after, cnot_count_after, t_count_after))

        f.write("%s,%d,%d,%d,%d,%d,%d,%f\n" % (fname, num_gates_before, cnot_count_before, t_count_before, num_gates_after, cnot_count_after, t_count_after, stop - start))
コード例 #2
0
ファイル: test_pyzx.py プロジェクト: philipp-q/tequila-1
def test_convert_to_from_pyzx_optimizing_circuit(tequila_circuit, t_reduce):

    pyzx_circuit = convert_to_pyzx(tequila_circuit)

    pyzx_graph = pyzx_circuit.to_graph()

    if t_reduce:
        pyzx.teleport_reduce(pyzx_graph)
        pyzx_circuit_opt = pyzx.Circuit.from_graph(pyzx_graph)
    else:
        pyzx.full_reduce(pyzx_graph)
        pyzx_graph.normalize()
        pyzx_circuit_opt = pyzx.extract_circuit(pyzx_graph.copy())

    # compare_tensors returns True if pyzx_circuit and pyzx_circuit_opt
    # implement the same circuit (up to global phase)
    assert (pyzx.compare_tensors(pyzx_circuit, pyzx_circuit_opt))

    # verify_equality return True if full_reduce() is able to reduce the
    # composition of the circuits to the identity
    assert (pyzx_circuit.verify_equality(pyzx_circuit_opt))

    converted_circuit = convert_from_pyzx(pyzx_circuit_opt)

    wfn1 = simulate(tequila_circuit, backend="symbolic")
    wfn2 = simulate(converted_circuit, backend="symbolic")

    assert (numpy.isclose(wfn1.inner(wfn2), 1.0))
コード例 #3
0
ファイル: run_pyzx.py プロジェクト: inQWIRE/mlvoqc
def run(d, fname):

    f = open(fname, "w")

    f.write("name,T,2q,total,time\n")

    for fname in os.listdir(d):

        print("Processing %s..." % fname)

        circ = zx.Circuit.load(os.path.join(d, fname)).to_basic_gates()

        start = time.perf_counter()
        g = circ.to_graph()
        zx.full_reduce(g, quiet=False)
        g.normalize()
        new_circ = zx.extract_circuit(g).to_basic_gates()
        stop = time.perf_counter()

        total_count = len(new_circ.gates)
        two_count = new_circ.twoqubitcount()
        t_count = zx.tcount(new_circ)

        print("\t Total %d, T %d, CNOT %d\n" %
              (total_count, t_count, two_count))

        f.write("%s,%d,%d,%d,%f\n" %
                (fname, t_count, two_count, total_count, stop - start))

    f.close()
コード例 #4
0
def remove_id(c, g):
    g_tmp = g.copy()
    for v in g.vertices():
        if basicrules.remove_id(g_tmp, v):
            try:
                c_new = zx.extract_circuit(g_tmp.copy())
                return True, (c_new, g_tmp)
            except:
                # If we can't extract the circuit, restore the graph and keep trying
                g_tmp = g.copy()
    return False, (c, g)
コード例 #5
0
def g_score(g):
    g_tmp = g.copy()

    # FIXME: VERY EXPENSIVE. only to enable circuit extraction.
    # A better strategy would be to probailistically full_reduce

    zx.full_reduce(g_tmp)
    c = zx.extract_circuit(g_tmp.copy()).to_basic_gates()
    c = zx.basic_optimization(c)

    return c_score(c)
    """
コード例 #6
0
def fuse(c, g):
    g_tmp = g.copy()
    for v1 in g.vertices():
        for v2 in g.vertices():
            if basicrules.fuse(g_tmp, v1, v2):
                try:
                    c_new = zx.extract_circuit(g_tmp.copy())
                    return True, (c_new, g_tmp)
                except:
                    # If we can't extract the circuit, restore the graph and keep trying
                    g_tmp = g.copy()
    return False, (c, g)
コード例 #7
0
def rand_lc(c, g, reduce_prob=0.1):
    g_tmp = g.copy()
    apply_rand_lc(g_tmp)

    # Note the work around to not always full_reduce the graph itself!
    g_fr = g_tmp.copy()
    zx.full_reduce(g_fr)
    c_new = zx.extract_circuit(g_fr.copy()).to_basic_gates()
    c_new = zx.basic_optimization(c_new)
    if random.uniform(0, 1) < reduce_prob:
        g_tmp = g_fr.copy()
    return True, (c_new, g_tmp)
コード例 #8
0
def full_reduce(c, g):
    # FIXME: Should really be using g_tmp here?
    orig_tcount = c.tcount()
    orig_2qubitcount = c.twoqubitcount()

    zx.full_reduce(g)
    c_opt = zx.extract_circuit(g.copy())

    opt_tcount = c_opt.tcount()
    opt_2qubitcount = c_opt.twoqubitcount()
    if orig_tcount == opt_tcount and orig_2qubitcount == opt_2qubitcount:
        return False, (c, g)
    return True, (c_opt, g)
コード例 #9
0
def strong_comp(c, g):
    g_tmp = g.copy()
    # n = g.num_vertices() # g.copy() will have consecutive vertices
    for v1 in g.vertices():
        for v2 in g.vertices():
            if basicrules.strong_comp(g_tmp, v1, v2):
                try:
                    c_new = zx.extract_circuit(g_tmp.copy())
                    return True, (c_new, g_tmp)
                except:
                    # If we can't extract the circuit, restore the graph and keep trying
                    g_tmp = g.copy()
    return False, (c, g)
コード例 #10
0
    def optimize(self):
        """
      Optimize the circuit using PyZX full_reduce optimization function
    """
        # transforming the PyZX circuit to a graph
        graph = self.circuit_zx.to_graph()
        zx.full_reduce(graph, quiet=True)

        # Optimizing the graph
        graph.normalize()

        # Extracting the circuit from the optimized graph
        self.circuit_zx = zx.extract_circuit(graph.copy())
        return self.circuit_zx
コード例 #11
0
def teleport_reduce(c, g):

    orig_tcount = c.tcount()
    orig_2qubitcount = c.twoqubitcount()

    zx.teleport_reduce(g)
    try:
        c_opt = zx.Circuit.from_graph(g)
    except:
        c_opt = zx.extract_circuit(g.copy())

    opt_tcount = c_opt.tcount()
    opt_2qubitcount = c_opt.twoqubitcount()
    if orig_tcount == opt_tcount and orig_2qubitcount == opt_2qubitcount:
        return False, (c, g)
    return True, (c_opt, g)
コード例 #12
0
def simp_base(c, g, simp_method):
    orig_tcount = c.tcount()
    orig_2qubitcount = c.twoqubitcount()

    g_tmp = g.copy()

    simp_method(g_tmp, quiet=True)
    try:
        # FIXME: WHY does this fail sometimes?
        c_opt = zx.extract_circuit(g_tmp.copy())
    except:
        return False, (c, g)

    opt_tcount = c_opt.tcount()
    opt_2qubitcount = c_opt.twoqubitcount()
    if orig_tcount == opt_tcount and orig_2qubitcount == opt_2qubitcount:
        return False, (c, g)
    return True, (c_opt, g_tmp)
コード例 #13
0
def pyzx_evaluation(circ: QuantumCircuit) -> QuantumCircuit:
    """
    Evaluation using the pyzx libary.

    due to compability issues, it needs to be casted from QSkits Circuit to the internal datastrcuture
    => check if this consumes to much memory
    :param circ:
    :return:
    """
    log.warning("Evaluating pyzx")
    c_graph = qiskit_circuit_to_zx_circuit(circ).to_graph()
    zx.simplify.full_reduce(c_graph)
    cir_reduced = zx.extract_circuit(
        c_graph).split_phase_gates().to_basic_gates()
    circ_out = zx_circuit_to_qiskit_circuit(cir_reduced)
    # circ_out = convert_clifford_t(circ_out)
    assert verify_equality(circ, circ_out)
    log.warning("done")
    return circ_out
コード例 #14
0
ファイル: ZXBuilder.py プロジェクト: seunomonije/mclang
    def _add_op_to_graph(self, operation: zx.gates.Gate,
                         graph: zx.Graph) -> zx.Graph:
        """Adds an operation to a PyZX graph by converting to
    circuit form, adding the operation to the circuit, then
    transitioning back to graph form.

    Args:
      operation: the operation to add to the graph.
      qubits: the qubit(s) on which the operation should be added.
              Note that for multi-qubit gates, the control gate(s)
              should be provided at the beginning of the list.
      graph: the graph to add the operation to.

    Returns:
      The overwritten graph with the operation added to it.
    """
        circuit = zx.extract_circuit(graph)
        circuit.add_gate(operation)
        returned_graph = circuit.to_graph()
        return returned_graph
コード例 #15
0
    def evolve(self, g, n_mutants, n_generations):
        self.n_mutants = n_mutants
        self.n_gens = n_generations

        self.g_orig = g.copy()
        to_graph_like(self.g_orig)
        self.c_orig = zx.extract_circuit(self.g_orig.copy()).to_basic_gates()
        self.c_orig = zx.basic_optimization(self.c_orig)

        # self.c_orig = c
        # self.g_orig = c.to_graph()
        # to_graph_like(self.g_orig)
        # self.mutants = [Mutant(c, self.g_orig) for _ in range(self.n_mutants)]
        self.mutants = [Mutant(self.c_orig, self.g_orig) for _ in range(self.n_mutants)]

        self.update_scores()
        best_mutant = min(self.mutants, key=lambda m: m.score) # FIXME: Check if this assignment is by reference or value
        best_score = best_mutant.score

        gen_scores = [best_score]
        best_scores = [best_score]
        for i in tqdm(range(self.n_gens), desc="Generations", disable=self.quiet):
            n_unique_mutants = len(list(set([id(m) for m in self.mutants])))
            assert(n_unique_mutants == self.n_mutants)

            self.mutate()
            # self.update_scores()
            best_in_gen = min(self.mutants, key=lambda m: m.score)
            gen_scores.append(best_in_gen.score) # So that if we never improve, we see each generation. Because our actions might all rely on extracting, we may never improve on the original
            if best_in_gen.score < best_score:
                best_mutant = deepcopy(best_in_gen)
                best_score = best_in_gen.score

            best_scores.append(best_score)
            if all([m.dead for m in self.mutants]):
                print("[_optimize] stopping early -- all mutants are dead")
                break

            self.select()

        return best_scores, gen_scores, best_mutant.c_curr
コード例 #16
0
def run(d, fname):

    f = open(fname, "w")

    f.write("name,T,2q,total,time\n")

    for fname in os.listdir(d):

        print("Processing %s..." % fname)

        circ = zx.Circuit.load(os.path.join(d, fname)).to_basic_gates()

        start = time.perf_counter()
        g = circ.to_graph()
        zx.full_reduce(g)
        g.normalize()
        opt_circ = zx.extract_circuit(g).to_basic_gates()
        stop = time.perf_counter()
        elapsed = stop - start
        if elapsed < TIMEOUT:
            try:  # try to run full_optimize, cancelling after 10 minutes - elapsed
                with time_limit(TIMEOUT - round(elapsed)):
                    opt_circ = zx.full_optimize(opt_circ)
                    stop = time.perf_counter()
            except TimeoutException:
                print("\tfull_optimize is slow; only running full_reduce")
        else:
            print("\tfull_optimize is slow; only running full_reduce")

        total_count = len(opt_circ.gates)
        two_count = opt_circ.twoqubitcount()
        t_count = zx.tcount(opt_circ)

        print("\tTotal %d, T %d, 2-qubit %d\n" %
              (total_count, t_count, two_count))

        f.write("%s,%d,%d,%d,%f\n" %
                (fname, t_count, two_count, total_count, stop - start))

    f.close()
コード例 #17
0
    axes[0].set_title(f"GA: {N_MUTANTS} mutants, {N_GENS} generations")
    axes[0].legend()

    ## SA part

    reductions = list()
    N_TRIALS = 10
    N_ITERS = 1000

    init_score = 4 * c_tr.twoqubitcount() + c_tr.tcount()
    for i in tqdm(range(N_TRIALS)):
        g_anneal, _ = sa.pivot_anneal(g_tr.copy(),
                                      iters=N_ITERS,
                                      score=sa.c_score)
        zx.full_reduce(g_anneal)
        c_anneal = zx.extract_circuit(g_anneal.copy()).to_basic_gates()
        c_anneal = zx.basic_optimization(c_anneal)

        trial_score = 4 * c_anneal.twoqubitcount() + c_anneal.tcount()
        reduction = (init_score - trial_score) / init_score * 100
        reductions.append(reduction)

        # print(f"\n----- trial {i} -----")
        # print(c_anneal.stats())
    """
    plt.hist(reductions)
    plt.xlabel("Reduction")
    plt.ylabel("Frequency")
    plt.title(f"SA: {N_TRIALS} trials, {N_ITERS} iters")
    """
コード例 #18
0
ファイル: ZXBuilder.py プロジェクト: seunomonije/mclang
 def to_circuit(self):
     return zx.extract_circuit(self.graph)
コード例 #19
0
        print("Can convert from original graph back to circuit")
    except:
        print("Can NOT convert from original graph back to circuit")

    successes = 0
    for _ in tqdm(range(1000)):
        c = zx.generate.CNOT_HAD_PHASE_circuit(qubits=N_QUBITS, depth=DEPTH, clifford=False)
        g = c.to_graph()
        zx.full_reduce(g)
        try:
            c_opt = zx.Circuit.from_graph(g)
            successes += 1
        except:
            continue
    print(f"Number of successes: {successes}")
    """

    # The below tests the graph-likeness utilities
    for _ in tqdm(range(100),
                  desc="Verifying equality with [to_graph_like]..."):
        c = zx.generate.CNOT_HAD_PHASE_circuit(qubits=N_QUBITS,
                                               depth=DEPTH,
                                               clifford=False)
        g = c.to_graph()
        g1 = g.copy()
        to_graph_like(g1)
        zx.full_reduce(g1)
        c1 = zx.extract_circuit(g1.copy())
        assert (c.verify_equality(c1))
    print("[to_graph_like] appears to maintain equality!")
コード例 #20
0
if __name__ == "__main__":
    N_QUBITS = 10
    DEPTH = 300

    c = zx.generate.CNOT_HAD_PHASE_circuit(qubits=N_QUBITS, depth=DEPTH, clifford=False)
    g = c.to_graph()

    reduce_tracker = zx.full_reduce_tracker(g, quiet=True)
    reduce_tracker['tcount'].insert(0, c.tcount())
    reduce_tracker['twoqubitcount'].insert(0, c.twoqubitcount())
    reduce_tracker['total'].insert(0, len(c.gates))
    reduce_tracker['edges'].insert(0, c.to_graph().num_edges())
    reduce_tracker['cliffordcount'].insert(0, c.cliffordcount())

    c_opt = zx.extract_circuit(g)
    print("-----FULL_REDUCE-----")
    print(f"T Count: {c.tcount()} -> {c_opt.tcount()}")
    print(f"2-qubit Count: {c.twoqubitcount()} -> {c_opt.twoqubitcount()}")
    print(f"Total Count: {len(c.gates)} -> {len(c_opt.gates)}")


    n_steps = len(reduce_tracker['total'])
    xs = list(range(n_steps))

    fig = plt.figure()
    ax1 = fig.add_subplot(111)
    ax1.plot(xs, reduce_tracker['tcount'], color='blue', label='T Count')
    ax1.plot(xs, reduce_tracker['total'], color='green', label='Total')
    ax1.plot(xs, reduce_tracker['twoqubitcount'], color='red', label='2-qubit count')
    ax1.plot(xs, reduce_tracker['edges'], color='purple', label='edges')
コード例 #21
0
 def _optimize(self, c):
     g = c.to_graph()
     zx.full_reduce(g, quiet=True)
     c_opt = zx.extract_circuit(g.copy()) # FIXME: maybe don't need g.copy()?
     return c_opt
コード例 #22
0
    DEPTH = 100
    c = zx.generate.CNOT_HAD_PHASE_circuit(qubits=N_QUBITS,
                                           depth=DEPTH,
                                           clifford=False)
    print("----- initial -----")
    print(c.stats())

    # zx.draw(c)
    plt.show()
    plt.close('all')

    g = c.to_graph()

    g_fr = g.copy()
    zx.full_reduce(g_fr)
    c_fr = zx.extract_circuit(g_fr.copy()).to_basic_gates()
    c_fr = zx.basic_optimization(c_fr)
    # note: we don't reset g_fr here because for any future annealing, we'd really optimize after the graph produced by full_reduce, rather than something resulting from extraction
    print("\n----- full_reduce + basic_optimization -----")
    print(c_fr.stats())

    g_just_tr = g.copy()
    zx.teleport_reduce(g_just_tr)
    c_just_tr = zx.Circuit.from_graph(g_just_tr.copy()).to_basic_gates()
    print("\n----- teleport_reduce -----")
    print(c_just_tr.stats())

    g_tr = g.copy()
    zx.teleport_reduce(g_tr)
    c_tr = zx.Circuit.from_graph(g_tr.copy()).to_basic_gates()
    # c_opt = zx.full_optimize(c_opt)
コード例 #23
0
    cs_thresholded = [(f, c) for (f, c) in bench_cs if c.qubits <= QUBIT_THRESHOLD]
    print(f"{len(bench_cs)} benchmark circuits, {len(cs_thresholded)} of which have at most {QUBIT_THRESHOLD} qubits")

    reductions = dict()

    for (f, c) in cs_thresholded[:3]:

        init_score = c_score(c)
        g = c.to_graph()
        g_tmp = g.copy()

        if METHOD == "FR":
            g_opt = g_tmp.copy()

            zx.full_reduce(g_opt)
            c_opt = zx.extract_circuit(g_opt.copy()).to_basic_gates()
            c_opt = zx.basic_optimization(c_opt)

            opt_score = c_score(c_opt)
        elif METHOD == "TR":
            g_opt = g_tmp.copy()

            zx.teleport_reduce(g_opt)
            c_opt = zx.Circuit.from_graph(g_opt.copy()).to_basic_gates()
            c_opt = zx.basic_optimization(c_opt)

            opt_score = c_score(c_opt)
            # g_opt = c_opt.to_graph()
        elif METHOD == "qiskit":
            c_opt = QISKIT_OPT._optimize(c.copy())