Esempio n. 1
0
    def run(self, circuit: Circuit, data: dict[str, Any]) -> None:
        """Perform the pass's operation, see BasePass for more info."""

        # Check data for windows markers
        if 'window_markers' not in data:
            _logger.warning('Did not find any window markers.')
            return

        window_markers = data['window_markers']
        _logger.debug('Found window_markers: %s.' % str(window_markers))

        if not is_iterable(window_markers):
            _logger.debug('Invalid type for window_markers.')
            return

        if not all(is_integer(marker) for marker in window_markers):
            _logger.debug('Invalid type for window_markers.')
            return

        # Resynthesis each window
        index_shift = 0
        for marker in window_markers:
            marker -= index_shift

            # Slice window
            begin_cycle = int(marker - self.window_size // 2)
            end_cycle = int(marker + np.ceil(self.window_size / 2))

            if begin_cycle < 0:
                begin_cycle = 0

            if end_cycle > circuit.get_num_cycles():
                end_cycle = circuit.get_num_cycles() - 1

            window = Circuit(circuit.get_size(), circuit.get_radixes())
            window.extend(circuit[begin_cycle:end_cycle])

            _logger.info(
                'Resynthesizing window from cycle '
                f'{begin_cycle} to {end_cycle}.', )

            # Synthesize
            utry = window.get_unitary()
            new_window = self.synthesispass.synthesize(utry, data)

            # Replace
            if self.replace_filter(new_window, window):
                _logger.debug('Replacing window with synthesized circuit.')

                actual_window_size = end_cycle - begin_cycle
                for _ in range(actual_window_size):
                    circuit.pop_cycle(begin_cycle)

                circuit.insert_circuit(
                    begin_cycle,
                    new_window,
                    list(range(circuit.get_size())),
                )

                index_shift += actual_window_size - new_window.get_num_cycles()
Esempio n. 2
0
 def test_empty(self) -> None:
     circuit = Circuit(1)
     assert circuit.get_size() == 1
     circuit = Circuit(4)
     assert circuit.get_size() == 4
     circuit = Circuit(4, [2, 2, 3, 3])
     assert circuit.get_size() == 4
Esempio n. 3
0
    def run(self, circuit: Circuit, data: dict[str, Any]) -> None:
        """Perform the pass's operation, see BasePass for more info."""

        # Collect CircuitGate blocks
        blocks: list[tuple[CircuitPoint, Operation]] = []
        for cycle, op in circuit.operations_with_cycles():
            if isinstance(op.gate, CircuitGate):
                blocks.append((cycle, op))

        # If a MachineModel is provided in the data dict, it will be used.
        # Otherwise all-to-all connectivity is assumed.
        model = None
        if 'machine_model' in data:
            model = data['machine_model']
        if (not isinstance(model, MachineModel)
                or model.num_qudits < circuit.get_size()):
            _logger.warning(
                'MachineModel not specified or invalid;'
                ' defaulting to all-to-all.', )
            model = MachineModel(circuit.get_size())

        subdata = data.copy()

        # Perform work
        points: list[CircuitPoint] = []
        ops: list[Operation] = []
        for cycle, op in blocks:
            gate: CircuitGate = op.gate
            subcircuit = gate._circuit.copy()
            subcircuit.set_params(op.params)

            subnumbering = {op.location[i]: i for i in range(len(op.location))}
            subdata['machine_model'] = MachineModel(
                len(op.location),
                model.get_subgraph(op.location, subnumbering),
            )

            for loop_pass in self.loop_body:
                loop_pass.run(circuit, subdata)

            if self.replace_filter(subcircuit, op):
                points.append(CircuitPoint(cycle, op.location[0]))
                ops.append(
                    Operation(
                        CircuitGate(subcircuit, True),
                        op.location,
                        subcircuit.get_params(),
                    ), )

            # TODO: Load freshly written data from subdata into data

        circuit.batch_replace(points, ops)
Esempio n. 4
0
 def test_qubits(self) -> None:
     circuit = Circuit(1, [2])
     assert circuit.get_size() == 1
     assert circuit.get_dim() == 2
     assert len(circuit.get_radixes()) == 1
     circuit.extend_qudits([2, 2])
     assert circuit.get_size() == 3
     assert circuit.get_dim() == 8
     assert len(circuit.get_radixes()) == 3
     circuit.extend_qudits([2, 2])
     assert circuit.get_size() == 5
     assert circuit.get_dim() == 32
     assert len(circuit.get_radixes()) == 5
Esempio n. 5
0
 def test_qutrits(self) -> None:
     circuit = Circuit(1, [3])
     assert circuit.get_size() == 1
     assert circuit.get_dim() == 3
     assert len(circuit.get_radixes()) == 1
     circuit.extend_qudits([3, 3])
     assert circuit.get_size() == 3
     assert circuit.get_dim() == 27
     assert len(circuit.get_radixes()) == 3
     circuit.extend_qudits([3, 3])
     assert circuit.get_size() == 5
     assert circuit.get_dim() == 243
     assert len(circuit.get_radixes()) == 5
Esempio n. 6
0
 def test_qutrit(self) -> None:
     circuit = Circuit(1, [3])
     assert circuit.get_size() == 1
     assert circuit.get_dim() == 3
     assert len(circuit.get_radixes()) == 1
     circuit.insert_qudit(0, 3)
     assert circuit.get_size() == 2
     assert circuit.get_dim() == 9
     assert len(circuit.get_radixes()) == 2
     circuit.insert_qudit(0, 3)
     assert circuit.get_size() == 3
     assert circuit.get_dim() == 27
     assert len(circuit.get_radixes()) == 3
Esempio n. 7
0
 def test_default(self) -> None:
     circuit = Circuit(1)
     assert circuit.get_size() == 1
     assert circuit.get_dim() == 2
     assert len(circuit.get_radixes()) == 1
     circuit.append_qudit()
     assert circuit.get_size() == 2
     assert circuit.get_dim() == 4
     assert len(circuit.get_radixes()) == 2
     circuit.append_qudit()
     assert circuit.get_size() == 3
     assert circuit.get_dim() == 8
     assert len(circuit.get_radixes()) == 3
Esempio n. 8
0
    def gen_initial_layer(
        self,
        target: UnitaryMatrix | StateVector,
        data: dict[str, Any],
    ) -> Circuit:
        """
        Generate the initial layer, see LayerGenerator for more.

        Raises:
            ValueError: If `target` has a radix mismatch with
                `self.initial_layer_gate`.
        """

        if not isinstance(target, (UnitaryMatrix, StateVector)):
            raise TypeError(
                'Expected unitary or state, got %s.' % type(target), )

        for radix in target.get_radixes():
            if radix != self.initial_layer_gate.get_radixes()[0]:
                raise ValueError(
                    'Radix mismatch between target and initial_layer_gate.', )

        init_circuit = Circuit(target.get_size(), target.get_radixes())
        for i in range(init_circuit.get_size()):
            init_circuit.append_gate(self.initial_layer_gate, [i])
        return init_circuit
Esempio n. 9
0
 def test_append_gate_5(self) -> None:
     circuit = Circuit(4)
     circuit.append_gate(CNOTGate(), [0, 1])
     circuit.append_gate(CNOTGate(), [1, 2])
     circuit.append_gate(CNOTGate(), [2, 3])
     circuit.insert_qudit(4)
     circuit.append_gate(CNOTGate(), [0, 3])
     assert circuit.get_size() == 5
     assert len(circuit.get_radixes()) == 5
     assert circuit.get_radixes().count(2) == 5
     assert circuit[3, 0].gate == CNOTGate()
     assert circuit[3, 0].location == (0, 3)
     assert circuit[0, 1].gate == CNOTGate()
     assert circuit[0, 1].location == (0, 1)
     assert circuit[1, 2].gate == CNOTGate()
     assert circuit[1, 2].location == (1, 2)
     assert circuit[2, 3].gate == CNOTGate()
     assert circuit[2, 3].location == (2, 3)
     assert circuit[3, 3].gate == CNOTGate()
     assert circuit[3, 3].location == (0, 3)
     assert circuit[0, 0].gate == CNOTGate()
     assert circuit[0, 0].location == (0, 1)
     assert circuit[1, 1].gate == CNOTGate()
     assert circuit[1, 1].location == (1, 2)
     assert circuit[2, 2].gate == CNOTGate()
     assert circuit[2, 2].location == (2, 3)
Esempio n. 10
0
 def test_append_gate_4(self, qudit_index: int) -> None:
     circuit = Circuit(4)
     circuit.append_gate(CNOTGate(), [0, 1])
     circuit.append_gate(CNOTGate(), [1, 2])
     circuit.append_gate(CNOTGate(), [2, 3])
     circuit.append_gate(CNOTGate(), [0, 1])
     circuit.append_gate(CNOTGate(), [1, 2])
     circuit.append_gate(CNOTGate(), [2, 3])
     circuit.append_gate(CNOTGate(), [0, 1])
     circuit.append_gate(CNOTGate(), [1, 2])
     circuit.append_gate(CNOTGate(), [2, 3])
     circuit.pop_qudit(qudit_index)
     assert circuit.get_size() == 3
     assert len(circuit.get_radixes()) == 3
     assert circuit.get_radixes().count(2) == 3
     assert circuit.get_num_operations() == 6
     assert circuit[0, 0].gate == CNOTGate()
     assert circuit[0, 0].location == (0, 1)
     assert circuit[1, 1].gate == CNOTGate()
     assert circuit[1, 1].location == (1, 2)
     assert circuit[2, 0].gate == CNOTGate()
     assert circuit[2, 0].location == (0, 1)
     assert circuit[3, 1].gate == CNOTGate()
     assert circuit[3, 1].location == (1, 2)
     assert circuit[4, 0].gate == CNOTGate()
     assert circuit[4, 0].location == (0, 1)
     assert circuit[5, 1].gate == CNOTGate()
     assert circuit[5, 1].location == (1, 2)
Esempio n. 11
0
    def run(self, circuit: Circuit, data: dict[str, Any]) -> None:
        """
        Partition gates in a circuit into a series of CircuitGates.

        Args:
            circuit (Circuit): Circuit to be partitioned.

            data (dict[str,Any]): Optional data unique to specific run.
        """

        if self.block_size > circuit.get_size():
            _logger.warning(
                'Configured block size is greater than circuit size; '
                'blocking entire circuit.',
            )
            circuit.fold({
                qudit_index: (0, circuit.get_num_cycles())
                for qudit_index in range(circuit.get_size())
            })
            return

        for i in range(self.num_points):
            # Pick best region of 4 random points
            best_region = None
            best_gates = 0

            for _ in range(4):
                cycle = 0
                qudit = 0
                while True:
                    cycle = np.random.randint(circuit.get_num_cycles())
                    qudit = np.random.randint(circuit.get_size())
                    if not circuit.is_point_idle((cycle, qudit)):
                        break

                region = circuit.surround((cycle, qudit), self.block_size)
                num_gates = len(circuit[region])

                if num_gates > best_gates:
                    best_gates = num_gates
                    best_region = region

            if best_region is None:
                raise RuntimeError('Unable to find a region.')

            circuit.fold(best_region)
Esempio n. 12
0
 def test_append_gate(self) -> None:
     circuit = Circuit(4)
     circuit.append_gate(CNOTGate(), [0, 1])
     circuit.append_gate(CNOTGate(), [1, 2])
     circuit.append_gate(CNOTGate(), [2, 3])
     circuit.append_qudit()
     circuit.append_gate(CNOTGate(), [3, 4])
     assert circuit.get_size() == 5
     assert circuit[3, 4].gate == CNOTGate()
Esempio n. 13
0
 def test_hybrid(self) -> None:
     circuit = Circuit(1)
     assert circuit.get_size() == 1
     assert circuit.get_dim() == 2
     assert len(circuit.get_radixes()) == 1
     circuit.append_qudit(4)
     assert circuit.get_size() == 2
     assert circuit.get_dim() == 8
     assert len(circuit.get_radixes()) == 2
     assert circuit.get_radixes()[0] == 2
     assert circuit.get_radixes()[1] == 4
     circuit.append_qudit(3)
     assert circuit.get_size() == 3
     assert circuit.get_dim() == 24
     assert len(circuit.get_radixes()) == 3
     assert circuit.get_radixes()[0] == 2
     assert circuit.get_radixes()[1] == 4
     assert circuit.get_radixes()[2] == 3
Esempio n. 14
0
 def test_hybrid(self) -> None:
     circuit = Circuit(1)
     assert circuit.get_size() == 1
     assert circuit.get_dim() == 2
     assert len(circuit.get_radixes()) == 1
     circuit.insert_qudit(0, 4)
     assert circuit.get_size() == 2
     assert circuit.get_dim() == 8
     assert len(circuit.get_radixes()) == 2
     assert circuit.get_radixes()[0] == 4
     assert circuit.get_radixes()[1] == 2
     circuit.insert_qudit(-1, 3)
     assert circuit.get_size() == 3
     assert circuit.get_dim() == 24
     assert len(circuit.get_radixes()) == 3
     assert circuit.get_radixes()[0] == 4
     assert circuit.get_radixes()[1] == 3
     assert circuit.get_radixes()[2] == 2
Esempio n. 15
0
 def test_index_invalid_empty(self) -> None:
     circuit = Circuit(1)
     assert circuit.get_size() == 1
     try:
         circuit.pop_qudit(0)
     except ValueError:
         return
     except BaseException:
         assert False, 'Unexpected Exception.'
Esempio n. 16
0
 def test_hybrid(self) -> None:
     circuit = Circuit(1)
     assert circuit.get_size() == 1
     assert circuit.get_dim() == 2
     assert len(circuit.get_radixes()) == 1
     circuit.extend_qudits([3, 4])
     assert circuit.get_size() == 3
     assert circuit.get_dim() == 24
     assert len(circuit.get_radixes()) == 3
     assert circuit.get_radixes()[0] == 2
     assert circuit.get_radixes()[1] == 3
     assert circuit.get_radixes()[2] == 4
     circuit.extend_qudits([3, 2])
     assert circuit.get_size() == 5
     assert circuit.get_dim() == 144
     assert len(circuit.get_radixes()) == 5
     assert circuit.get_radixes()[0] == 2
     assert circuit.get_radixes()[1] == 3
     assert circuit.get_radixes()[2] == 4
     assert circuit.get_radixes()[3] == 3
     assert circuit.get_radixes()[4] == 2
Esempio n. 17
0
 def test_with_fold(self, r6_qudit_circuit: Circuit) -> None:
     cycle = 0
     qudit = 0
     while True:
         cycle = np.random.randint(r6_qudit_circuit.get_num_cycles())
         qudit = np.random.randint(r6_qudit_circuit.get_size())
         if not r6_qudit_circuit.is_point_idle((cycle, qudit)):
             break
     utry = r6_qudit_circuit.get_unitary()
     region = r6_qudit_circuit.surround((cycle, qudit), 4)
     r6_qudit_circuit.fold(region)
     assert r6_qudit_circuit.get_unitary() == utry
Esempio n. 18
0
    def gen_successors(
        self,
        circuit: Circuit,
        data: dict[str, Any],
    ) -> list[Circuit]:
        """
        Generate the successors of a circuit node.

        Raises:
            ValueError: If circuit is a single-qudit circuit.
        """

        if not isinstance(circuit, Circuit):
            raise TypeError('Expected circuit, got %s.' % type(circuit))

        if circuit.get_size() < 2:
            raise ValueError('Cannot expand a single-qudit circuit.')

        # If a MachineModel is provided in the data dict, it will be used.
        # Otherwise all-to-all connectivity is assumed.
        model = None
        if 'machine_model' in data:
            model = data['machine_model']
        if (not isinstance(model, MachineModel)
                or model.num_qudits < circuit.get_size()):
            _logger.warning(
                'MachineModel not specified or invalid;'
                ' defaulting to all-to-all.', )
            model = MachineModel(circuit.get_size())

        # TODO: Reconsider linear topology default
        successors = []
        for edge in model.coupling_graph:
            successor = circuit.copy()
            successor.append_gate(self.two_qudit_gate, [edge[0], edge[1]])
            successor.append_gate(self.single_qudit_gate_1, edge[0])
            successor.append_gate(self.single_qudit_gate_2, edge[1])
            successors.append(successor)

        return successors
Esempio n. 19
0
    def test_correctness_1(self, r6_qudit_circuit: Circuit) -> None:
        for x in range(r6_qudit_circuit.get_num_cycles()):
            for y in range(r6_qudit_circuit.get_size()):
                correct = r6_qudit_circuit._circuit[x][y]

                if correct is not None:
                    assert correct is r6_qudit_circuit.get_operation((x, y))

                else:
                    try:
                        r6_qudit_circuit.get_operation((x, y))
                    except IndexError:
                        pass
                    except BaseException:
                        assert False, 'Unexpected exception.'
Esempio n. 20
0
    def test_correctness_1(self, r6_qudit_circuit: Circuit) -> None:
        for x in range(r6_qudit_circuit.get_num_cycles()):
            for y in range(r6_qudit_circuit.get_size()):
                op = r6_qudit_circuit._circuit[x][y]

                if op is not None:
                    point = r6_qudit_circuit.point(op, (x, y))
                    assert r6_qudit_circuit.get_operation(point) is op
                    point = r6_qudit_circuit.point(op, (x, y), (x, y))
                    assert r6_qudit_circuit.get_operation(point) is op

                    point = r6_qudit_circuit.point(op.gate, (x, y))
                    assert r6_qudit_circuit.get_operation(point) is op
                    point = r6_qudit_circuit.point(op.gate, (x, y), (x, y))
                    assert r6_qudit_circuit.get_operation(point) is op
Esempio n. 21
0
 def test_multi_gate_3(self, gen_random_utry_np: Any) -> None:
     circuit = Circuit(4)
     three_qubit_gate = ConstantUnitaryGate(
         gen_random_utry_np(12), [2, 2, 3],
     )
     circuit.insert_qudit(2, 3)
     assert circuit.get_size() == 5
     assert len(circuit.get_radixes()) == 5
     assert circuit.get_radixes()[0] == 2
     assert circuit.get_radixes()[1] == 2
     assert circuit.get_radixes()[2] == 3
     assert circuit.get_radixes()[3] == 2
     assert circuit.get_radixes()[4] == 2
     circuit.append_gate(three_qubit_gate, [0, 1, 2])
     assert circuit[0, 0].gate == three_qubit_gate
     assert circuit[0, 0].location == (0, 1, 2)
Esempio n. 22
0
 def test_multi_gate_1(self, gen_random_utry_np: Any) -> None:
     circuit = Circuit(4)
     three_qubit_gate = ConstantUnitaryGate(gen_random_utry_np(8))
     circuit.append_gate(three_qubit_gate, [1, 2, 3])
     circuit.append_gate(three_qubit_gate, [0, 2, 3])
     circuit.append_gate(three_qubit_gate, [0, 1, 3])
     circuit.append_gate(three_qubit_gate, [0, 1, 2])
     circuit.insert_qudit(0)
     assert circuit.get_size() == 5
     assert len(circuit.get_radixes()) == 5
     assert circuit.get_radixes().count(2) == 5
     assert circuit[0, 2].gate == three_qubit_gate
     assert circuit[0, 2].location == (2, 3, 4)
     assert circuit[1, 1].gate == three_qubit_gate
     assert circuit[1, 1].location == (1, 3, 4)
     assert circuit[2, 1].gate == three_qubit_gate
     assert circuit[2, 1].location == (1, 2, 4)
     assert circuit[3, 1].gate == three_qubit_gate
     assert circuit[3, 1].location == (1, 2, 3)
Esempio n. 23
0
 def test_multi_gate_1(
         self, qudit_index: int, gen_random_utry_np: Any,
 ) -> None:
     circuit = Circuit(4)
     three_qubit_gate = ConstantUnitaryGate(gen_random_utry_np(8))
     circuit.append_gate(three_qubit_gate, [1, 2, 3])
     circuit.append_gate(three_qubit_gate, [0, 2, 3])
     circuit.append_gate(three_qubit_gate, [0, 1, 3])
     circuit.append_gate(three_qubit_gate, [0, 1, 2])
     circuit.pop_qudit(qudit_index)
     assert circuit.get_size() == 3
     assert len(circuit.get_radixes()) == 3
     assert circuit.get_radixes().count(2) == 3
     assert circuit.get_num_operations() == 1
     assert circuit.get_num_cycles() == 1
     assert circuit[0, 0].gate == three_qubit_gate
     assert circuit[0, 0].location == (0, 1, 2)
     assert circuit[0, 1].gate == three_qubit_gate
     assert circuit[0, 1].location == (0, 1, 2)
     assert circuit[0, 2].gate == three_qubit_gate
     assert circuit[0, 2].location == (0, 1, 2)
Esempio n. 24
0
 def test_type(self, r6_qudit_circuit: Circuit) -> None:
     assert isinstance(r6_qudit_circuit.get_size(), int)
Esempio n. 25
0
 def test_get_size(self, toffoli_circuit: Circuit) -> None:
     assert toffoli_circuit.get_size() == 3
Esempio n. 26
0
 def test_get_radixes(self, simple_circuit: Circuit) -> None:
     assert len(simple_circuit.get_radixes()) == simple_circuit.get_size()
     assert isinstance(simple_circuit.get_radixes(), tuple)
     assert all(r == 2 for r in simple_circuit.get_radixes())
Esempio n. 27
0
 def test_get_size(self, simple_circuit: Circuit) -> None:
     assert simple_circuit.get_size() == 2
Esempio n. 28
0
    def run(self, circuit: Circuit, data: dict[str, Any]) -> None:
        """
        Partition gates in a circuit into a series of CircuitGates.

        Args:
            circuit (Circuit): Circuit to be partitioned.

            data (dict[str,Any]): Optional data unique to specific run.
        """

        if self.block_size > circuit.get_size():
            _logger.warning(
                'Configured block size is greater than circuit size; '
                'blocking entire circuit.', )
            circuit.fold({
                qudit_index: (0, circuit.get_num_cycles())
                for qudit_index in range(circuit.get_size())
            })
            return

        # If a MachineModel is provided in the data dict, it will be used.
        # Otherwise all-to-all connectivity is assumed.
        model = None

        if 'machine_model' in data:
            model = data['machine_model']

        if (not isinstance(model, MachineModel)
                or model.num_qudits < circuit.get_size()):
            _logger.warning(
                'MachineModel not specified or invalid;'
                ' defaulting to all-to-all.', )
            model = MachineModel(circuit.get_size())

        # Find all connected, `block_size`-sized groups of qudits
        # NOTE: This assumes circuit and topology qudit numbers are equal
        qudit_groups = model.get_locations(self.block_size)
        # Prune unused qudit groups
        used_qudits = [
            q for q in range(circuit.get_size())
            if not circuit.is_qudit_idle(q)
        ]
        for qudit_group in qudit_groups:
            if all([q not in used_qudits for q in qudit_group]):
                qudit_groups.remove(qudit_group)

        # divider splits the circuit into partitioned and unpartitioned spaces.
        active_qudits = circuit.get_active_qudits()
        num_cycles = circuit.get_num_cycles()
        divider = [
            0 if q in active_qudits else num_cycles
            for q in range(circuit.get_size())
        ]

        # Form regions until there are no more gates to partition
        regions: list[CircuitRegion] = []
        while any(cycle < num_cycles for cycle in divider):

            # Move past/skip any gates that are larger than block size
            qudits_to_increment: list[int] = []
            for qudit, cycle in enumerate(divider):
                if qudit in qudits_to_increment or cycle >= num_cycles:
                    continue

                if not circuit.is_point_idle((cycle, qudit)):
                    op = circuit[cycle, qudit]
                    if len(op.location) > self.block_size:
                        if all(divider[q] == cycle for q in op.location):
                            qudits_to_increment.extend(op.location)
                            _logger.warning(
                                'Skipping gate larger than block size.', )

            if len(qudits_to_increment) > 0:
                regions.append(
                    CircuitRegion(
                        {
                            qudit: (divider[qudit], divider[qudit])
                            for qudit in qudits_to_increment
                        }, ), )

            for qudit in qudits_to_increment:
                divider[qudit] += 1

            # Skip any idle qudit-cycles
            amount_to_add_to_each_qudit = [
                0 for _ in range(circuit.get_size())
            ]
            for qudit, cycle in enumerate(divider):
                while (cycle < num_cycles and circuit.is_point_idle(
                    (cycle, qudit))):
                    amount_to_add_to_each_qudit[qudit] += 1
                    cycle += 1

            for qudit, amount in enumerate(amount_to_add_to_each_qudit):
                divider[qudit] += amount

            # Find the scores of the qudit groups.
            best_score = None
            best_region = None

            for qudit_group in qudit_groups:

                ops_and_cycles = circuit.operations_with_cycles(
                    qudits_or_region=CircuitRegion({
                        qudit_index: (divider[qudit_index], num_cycles)
                        for qudit_index in qudit_group
                    }), )

                in_qudits = list(q for q in qudit_group)
                stopped_cycles = {q: num_cycles for q in qudit_group}
                score = 0

                for cycle, op in ops_and_cycles:
                    if len(op.location.union(in_qudits)) != len(in_qudits):
                        for qudit_index in op.location.intersection(in_qudits):
                            stopped_cycles[qudit_index] = cycle
                            in_qudits.remove(qudit_index)
                    else:
                        if len(op.location) > 1:
                            score += self.multi_gate_score
                        else:
                            score += self.single_gate_score

                    if len(in_qudits) == 0:
                        break

                if best_score is None or score > best_score:
                    best_score = score
                    best_region = CircuitRegion({
                        qudit: (
                            divider[qudit],
                            # Might have errors if below is removed
                            stopped_cycles[qudit] - 1,
                        )
                        for qudit in qudit_group
                        # This statement
                        # if stopped_cycles[qudit] - 1 >= divider[qudit]
                    })

            if best_score is None or best_region is None:
                raise RuntimeError('No valid block found.')

            _logger.info('Found block with score: %d.' % (best_score))
            regions.append(best_region)

            # Update divider
            for qudit_index in best_region:
                divider[qudit_index] = best_region[qudit_index].upper + 1

        # Fold the circuit
        folded_circuit = Circuit(circuit.get_size(), circuit.get_radixes())
        # Option to keep a block's idle qudits as part of the CircuitGate
        if 'keep_idle_qudits' in data and data['keep_idle_qudits'] is True:
            for region in regions:
                small_region = circuit.downsize_region(region)
                cgc = circuit.get_slice(small_region.points)
                if len(region.location) > len(small_region.location):
                    for i in range(len(region.location)):
                        if region.location[i] not in small_region.location:
                            cgc.insert_qudit(i)
                folded_circuit.append_gate(
                    CircuitGate(cgc, True),
                    sorted(list(region.keys())),
                    list(cgc.get_params()),
                )
        else:
            for region in regions:
                region = circuit.downsize_region(region)
                if 0 < len(region) <= self.block_size:
                    cgc = circuit.get_slice(region.points)
                    folded_circuit.append_gate(
                        CircuitGate(cgc, True),
                        sorted(list(region.keys())),
                        list(cgc.get_params()),
                    )
                else:
                    folded_circuit.extend(circuit[region])
        circuit.become(folded_circuit)
Esempio n. 29
0
 def test_get_radixes(self, toffoli_circuit: Circuit) -> None:
     assert len(toffoli_circuit.get_radixes()) == toffoli_circuit.get_size()
     assert isinstance(toffoli_circuit.get_radixes(), tuple)
     assert all(r == 2 for r in toffoli_circuit.get_radixes())
Esempio n. 30
0
 def test_value(self, r6_qudit_circuit: Circuit) -> None:
     assert r6_qudit_circuit.get_size() == 6