def run(self, circuit: Circuit, data: dict[str, Any]) -> None: """Perform the pass's operation, see BasePass for more info.""" start = 'left' if self.start_from_left else 'right' _logger.debug(f'Starting scan gate removal from {start}.') target = circuit.get_unitary() circuit_copy = circuit.copy() reverse_iter = not self.start_from_left for cycle, op in circuit.operations_with_cycles(reverse=reverse_iter): if not self.collection_filter(op): _logger.debug(f'Skipping operation {op} at cycle {cycle}.') continue _logger.info(f'Attempting removal of operation at cycle {cycle}.') _logger.debug(f'Operation: {op}') working_copy = circuit_copy.copy() # If removing gates from the left, we need to track index changes. if self.start_from_left: idx_shift = circuit.get_num_cycles() idx_shift -= working_copy.get_num_cycles() cycle -= idx_shift working_copy.pop((cycle, op.location[0])) working_copy.instantiate(target, **self.instantiate_options) if self.cost(working_copy, target) < self.success_threshold: _logger.info('Successfully removed operation.') circuit_copy = working_copy circuit.become(circuit_copy)
def __init__(self, circuit: Circuit, move: bool = False) -> None: """ CircuitGate Constructor. Args: circuit (Circuit): The circuit to copy into gate format. move (bool): If true, the constructor will not copy the circuit. This should only be used when you are sure `circuit` will no longer be used on caller side. If unsure use the default. (Default: False) """ self._circuit = circuit if move else circuit.copy() self.size = self._circuit.get_size() self.radixes = self._circuit.get_radixes() self.utry = self._circuit.get_unitary() self.num_params = self._circuit.get_num_params() self.name = 'CircuitGate(%s)' % str(self._circuit)
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
def save_checkpoint(circuit: Circuit, path: str, num: int) -> None: circuit_copy = circuit.copy() VariableToU3Pass().run(circuit_copy, {}) PauliToU3Pass().run(circuit_copy, {}) with open(path + f'/block_{num}', 'w') as f: f.write(OPENQASM2Language().encode(circuit_copy))