Example #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()
Example #2
0
    def is_location(location: Any, num_qudits: int | None = None) -> bool:
        """
        Determines if the sequence of qudits form a valid location. A valid
        location is a set of qubit indices (integers) that are greater than or
        equal to zero, and if num_qudits is specified, less than num_qudits.

        Args:
            location (Any): The location to check.

            num_qudits (int | None): The total number of qudits.
                All qudit indices should be less than this. If None,
                don't check.

        Returns:
            (bool): True if the location is valid.
        """
        if isinstance(location, CircuitLocation):
            if num_qudits is not None:
                return max(location) < num_qudits
            return True

        if is_integer(location):
            location = [location]

        if not is_iterable(location):
            _logger.debug(
                'Expected iterable of integers for location'
                f', got {type(location)}.',
            )
            return False

        if not all(is_integer(qudit_index) for qudit_index in location):
            checks = [is_integer(qudit_index) for qudit_index in location]
            _logger.debug(
                'Expected iterable of integers for location'
                f', got atleast one {type(location[checks.index(False)])}.',
            )
            return False

        if not all(qudit_index >= 0 for qudit_index in location):
            checks = [qudit_index >= 0 for qudit_index in location]
            _logger.debug(
                'Expected iterable of positive integers for location'
                f', got atleast one {location[checks.index(False)]}.',
            )
            return False

        if len(set(location)) != len(location):
            _logger.debug('Location has duplicate qudit indices.')
            return False

        if num_qudits is not None:
            if not all([qudit < num_qudits for qudit in location]):
                _logger.debug('Location has an erroneously large qudit.')
                return False

        return True
Example #3
0
    def test_base_false(self) -> None:
        # Numbers are not iterable
        assert not typing.is_iterable(0)
        assert not typing.is_iterable(-1)
        assert not typing.is_iterable(1)
        assert not typing.is_iterable(1.0)
        assert not typing.is_iterable(1.0 + 2.0j)

        # Booleans are not iterable
        assert not typing.is_iterable(False)
        assert not typing.is_iterable(True)

        # Callables are not iterable
        assert not typing.is_iterable(lambda x: 0)

        # Modules are not iterable
        assert not typing.is_iterable(typing)
Example #4
0
    def test_base_true(self) -> None:
        # Sequences are iterable
        assert typing.is_iterable('TestString')
        assert typing.is_iterable((0, 1))
        assert typing.is_iterable((0, ))
        assert typing.is_iterable([])
        assert typing.is_iterable([0, 1])

        # Sets and Dicts are also iterable
        assert typing.is_iterable({0, 1})
        assert typing.is_iterable({0: 1, 1: 2})
Example #5
0
    def gate(self, args: Any) -> None:
        gate_name = args.children[0]
        param_list = None if len(args.children) == 2 else args.children[1]
        if len(args.children) == 2:
            var_list = args.children[1]
        else:
            var_list = args.children[2]

        if gate_name not in self.gate_defs:
            raise LangException('Unrecognized gate: %s.' % gate_name)

        gate_def = self.gate_defs[gate_name]

        # Calculate params
        params = []
        if param_list is not None:
            if is_iterable(eval_explist(param_list)):
                params = [float(i) for i in eval_explist(param_list)]
            else:
                params = [float(eval_explist(param_list))]

        if len(params) != gate_def.num_params:
            raise LangException(
                'Expected %d params got %d params for gate %s.' %
                (gate_def.num_params, len(params), gate_name), )

        # Calculate location
        location = []
        for reg_name, reg_idx in qubits_from_list(var_list):
            outer_idx = 0
            for reg in self.qubit_regs:
                if reg.name == reg_name:
                    location.append(outer_idx + reg_idx)
                    break
                outer_idx += reg.size

        if len(location) != gate_def.num_vars:
            raise LangException(
                'Gate acts on %d qubits, got %d qubit variables.' %
                (gate_def.num_vars, len(location)), )

        # Calculate operation
        self.op_list.append(Operation(gate_def.gate, location, params))
Example #6
0
    def __init__(self, location: int | Iterable[int]) -> None:
        """
        Construct a CircuitLocation from `location`.

        Args:
            location (int | Iterable[int]): The qudit indices.

        Raises:
            ValueError: If any qudit index is negative.

            ValueError: If there are duplicates in location.
        """

        if is_integer(location):  # TODO: Typeguard
            location = [location]  # type: ignore

        assert not isinstance(location, int)  # TODO: Typeguard
        location = list(location)

        if not is_iterable(location):
            raise TypeError(
                'Expected iterable of integers for location'
                f', got {type(location)}.',
            )

        if not all(is_integer(qudit_index) for qudit_index in location):
            checks = [is_integer(qudit_index) for qudit_index in location]
            raise TypeError(
                'Expected iterable of integers for location'
                f', got atleast one {type(location[checks.index(False)])}.',
            )

        if not all(qudit_index >= 0 for qudit_index in location):
            checks = [qudit_index >= 0 for qudit_index in location]
            raise ValueError(
                'Expected iterable of positive integers for location'
                f', got atleast one {location[checks.index(False)]}.',
            )

        if len(set(location)) != len(location):
            raise ValueError('Location has duplicate qudit indices.')

        self._location: tuple[int, ...] = tuple(location)
Example #7
0
 def test_circuit(self, swap_circuit: Circuit) -> None:
     # Circuits are iterable
     assert typing.is_iterable(swap_circuit)
Example #8
0
 def test_gates(self, gate: Gate) -> None:
     # Gates are not iterable
     assert not typing.is_iterable(gate)