示例#1
0
    def optimize_circuit(self, circuit: Circuit):
        frontier = defaultdict(lambda: 0)  # type: Dict[QubitId, int]
        i = 0
        while i < len(circuit):  # Note: circuit may mutate as we go.
            for op in circuit[i].operations:
                # Don't touch stuff inserted by previous optimizations.
                if any(frontier[q] > i for q in op.qubits):
                    continue

                # Skip if an optimization removed the circuit underneath us.
                if i >= len(circuit):
                    continue
                # Skip if an optimization removed the op we're considering.
                if op not in circuit[i].operations:
                    continue
                opt = self.optimization_at(circuit, i, op)
                # Skip if the optimization did nothing.
                if opt is None:
                    continue

                # Clear target area, and insert new operations.
                circuit.clear_operations_touching(
                    opt.clear_qubits,
                    [e for e in range(i, i + opt.clear_span)])
                new_operations = self.post_clean_up(opt.new_operations)
                circuit.insert_at_frontier(new_operations, i, frontier)

            i += 1
示例#2
0
    def optimize_circuit(self, circuit: Circuit):
        walls = defaultdict(lambda: 0)  # type: Dict[QubitId, int]
        i = 0
        while i < len(circuit.moments):  # Note: circuit may mutate as we go.
            for op in circuit.moments[i].operations:
                # Don't touch stuff inserted by previous optimizations.
                if any(walls[q] > i for q in op.qubits):
                    continue

                # Skip if an optimization removed the circuit underneath us.
                if i >= len(circuit.moments):
                    continue
                # Skip if an optimization removed the op we're considering.
                if op not in circuit.moments[i].operations:
                    continue
                opt = self.optimization_at(circuit, i, op)
                # Skip if the optimization did nothing.
                if opt is None:
                    continue

                # Clear target area, and insert new operations.
                circuit.clear_operations_touching(
                    opt.clear_qubits,
                    [e for e in range(i, i + opt.clear_span)])
                next_insert_index = circuit.insert_into_range(
                    opt.new_operations, i, i + opt.clear_span)

                # Prevent redundant optimizations.
                for q in opt.clear_qubits:
                    walls[q] = max(walls[q], next_insert_index)

            i += 1
示例#3
0
    def optimize_circuit(self, circuit: Circuit):
        frontier = defaultdict(lambda: 0)  # type: Dict[QubitId, int]
        i = 0
        while i < len(circuit):  # Note: circuit may mutate as we go.
            for op in circuit[i].operations:
                # Don't touch stuff inserted by previous optimizations.
                if any(frontier[q] > i for q in op.qubits):
                    continue

                # Skip if an optimization removed the circuit underneath us.
                if i >= len(circuit):
                    continue
                # Skip if an optimization removed the op we're considering.
                if op not in circuit[i].operations:
                    continue
                opt = self.optimization_at(circuit, i, op)
                # Skip if the optimization did nothing.
                if opt is None:
                    continue

                # Clear target area, and insert new operations.
                circuit.clear_operations_touching(
                    opt.clear_qubits,
                    [e for e in range(i, i + opt.clear_span)])
                circuit.insert_at_frontier(opt.new_operations, i, frontier)

            i += 1
示例#4
0
    def optimize_circuit(self, circuit: Circuit):
        frontier: Dict['Qid', int] = defaultdict(lambda: 0)
        i = 0
        while i < len(circuit):  # Note: circuit may mutate as we go.
            for op in circuit[i].operations:
                # Don't touch stuff inserted by previous optimizations.
                if any(frontier[q] > i for q in op.qubits):
                    continue

                # Skip if an optimization removed the circuit underneath us.
                if i >= len(circuit):
                    continue
                # Skip if an optimization removed the op we're considering.
                if op not in circuit[i].operations:
                    continue
                opt = self.optimization_at(circuit, i, op)
                # Skip if the optimization did nothing.
                if opt is None:
                    continue

                # Clear target area, and insert new operations.
                circuit.clear_operations_touching(
                    opt.clear_qubits,
                    [e for e in range(i, i + opt.clear_span)])
                new_operations = self.post_clean_up(
                    cast(Tuple[ops.Operation], opt.new_operations))

                flat_new_operations = tuple(ops.flatten_to_ops(new_operations))

                new_qubits = set()
                for flat_op in flat_new_operations:
                    for q in flat_op.qubits:
                        new_qubits.add(q)

                if not new_qubits.issubset(set(opt.clear_qubits)):
                    raise ValueError(
                        'New operations in PointOptimizer should not act on new qubits.'
                    )

                circuit.insert_at_frontier(flat_new_operations, i, frontier)
            i += 1
示例#5
0
    def optimize_circuit(self, circuit: Circuit):
        moment_new_ops = defaultdict(
            list)  # type: Dict[int, List['cirq.Operation']]
        circuit_len = len(circuit)
        for i in range(circuit_len):
            moment_new_ops[i] = []
            for op in circuit[i].operations:
                opt = self.optimization_at(circuit, i, op)
                if opt is None:
                    # keep the old operation if the optimization did nothing.
                    moment_new_ops[i].append(op)
                    circuit.clear_operations_touching(op.qubits, [i])
                else:
                    # Clear target area, and insert new operations.
                    circuit.clear_operations_touching(
                        opt.clear_qubits,
                        [e for e in range(i, i + opt.clear_span)])
                    new_operations = self.post_clean_up(
                        cast(Tuple[ops.Operation], opt.new_operations))

                    flat_new_operations = tuple(
                        ops.flatten_to_ops(new_operations))

                    new_qubits = set()
                    for flat_op in flat_new_operations:
                        for q in flat_op.qubits:
                            new_qubits.add(q)

                    if not new_qubits.issubset(set(opt.clear_qubits)):
                        raise ValueError(
                            'New operations in PointOptimizer should not act on new'
                            ' qubits.')
                    moment_new_ops[i].extend(flat_new_operations)
        frontier = 0
        for i in range(circuit_len):
            new_frontier = circuit.insert(frontier, moment_new_ops[i],
                                          InsertStrategy.EARLIEST_AFTER)
            if frontier < new_frontier:
                frontier = new_frontier
示例#6
0
def test_clear_operations_touching():
    a = cirq.QubitId()
    b = cirq.QubitId()

    c = Circuit()
    c.clear_operations_touching([a, b], range(10))
    assert c == Circuit()

    c = Circuit([
        Moment(),
        Moment([cirq.X(a), cirq.X(b)]),
        Moment([cirq.X(a)]),
        Moment([cirq.X(a)]),
        Moment([cirq.CZ(a, b)]),
        Moment(),
        Moment([cirq.X(b)]),
        Moment(),
    ])
    c.clear_operations_touching([a], [1, 3, 4, 6, 7])
    assert c == Circuit([
        Moment(),
        Moment([cirq.X(b)]),
        Moment([cirq.X(a)]),
        Moment(),
        Moment(),
        Moment(),
        Moment([cirq.X(b)]),
        Moment(),
    ])

    c = Circuit([
        Moment(),
        Moment([cirq.X(a), cirq.X(b)]),
        Moment([cirq.X(a)]),
        Moment([cirq.X(a)]),
        Moment([cirq.CZ(a, b)]),
        Moment(),
        Moment([cirq.X(b)]),
        Moment(),
    ])
    c.clear_operations_touching([a, b], [1, 3, 4, 6, 7])
    assert c == Circuit([
        Moment(),
        Moment(),
        Moment([cirq.X(a)]),
        Moment(),
        Moment(),
        Moment(),
        Moment(),
        Moment(),
    ])