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()
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
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)
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})
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))
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)
def test_circuit(self, swap_circuit: Circuit) -> None: # Circuits are iterable assert typing.is_iterable(swap_circuit)
def test_gates(self, gate: Gate) -> None: # Gates are not iterable assert not typing.is_iterable(gate)