def is_gate_executable(self, gate: Gate, qubit_mapping: dict) -> bool: """Determines if a 2 qubut gate is executable, i.e., whether the gate acts on qubits which are connected in the coupling graph Args: gate (Gate): input 2 qubit gate qubit_mapping (dict): logical to physical qubit mapping Returns: bool: True if the input gate acts on connected qubits. False otherwise """ gate_qubits = list(gate.get_qubits()) logical_qubit_1, logical_qubit_2 = gate_qubits[0], gate_qubits[1] physical_qubit_1, physical_qubit_2 = qubit_mapping.get( logical_qubit_1), qubit_mapping.get(logical_qubit_2) return self.coupling_graph.has_edge(physical_qubit_1, physical_qubit_2)
def update_decay_parameter(self, min_score_swap_gate: Gate, decay_parameter: list) -> list: """Updates decay parameters for qubits on which SWAP gate with the minimum heuristic score is applied Args: min_score_swap_gate (Gate): SWAP gate with the minimum heuristic score decay_parameter (list): decay parameter list to be updated Returns: list: updated decay parameter list """ min_score_swap_qubits = list(min_score_swap_gate.get_qubits()) decay_parameter[min_score_swap_qubits[0]] = decay_parameter[ min_score_swap_qubits[0]] + 0.001 decay_parameter[min_score_swap_qubits[1]] = decay_parameter[ min_score_swap_qubits[1]] + 0.001 return decay_parameter
def update_initial_mapping(self, swap_gate: Gate, qubit_mapping: dict) -> dict: """Update qubit mapping between logical and physical if a SWAP gate is inserted in the program Args: swap_gate (Gate): a pyquil SWAP gate qubit_mapping (dict): a dictionary containing logical to physical qubit mapping Returns: dict: updated qubit mapping """ temp_mapping = qubit_mapping.copy() swap_qubits = list(swap_gate.get_qubits()) p_qubit_1, p_qubit_2 = qubit_mapping.get( swap_qubits[0]), qubit_mapping.get(swap_qubits[1]) p_qubit_1, p_qubit_2 = p_qubit_2, p_qubit_1 temp_mapping.update({ swap_qubits[0]: p_qubit_1, swap_qubits[1]: p_qubit_2 }) return temp_mapping
def heuristic_function(F: list, circuit_dag: DiGraph, initial_mapping: dict, distance_matrix: np.matrix, swap_gate: Gate, decay_parameter: list) -> float: """Computes a heuristic cost function that is used to rate a candidate SWAP to determine whether the SWAP gate can be inserted in a program to resolve qubit dependencies Args: F (list): list of gates that have no unexecuted predecessors in the DAG circuit_dag (DiGraph): a directed acyclic graph representing qubit dependencies between gates initial_mapping (dict): a dictionary containing logical to physical qubit mapping distance_matrix (np.matrix): represents qubit connections from given coupling graph swap_gate (Gate): candidate SWAP gate decay_parameter (list): decay parameters for each logical qubit in the mapping Returns: float: heuristic score for the candidate SWAP gate """ E = create_extended_successor_set(F, circuit_dag) min_score_swap_qubits = list(swap_gate.get_qubits()) size_E = len(E) size_F = len(F) W = 0.5 max_decay = max(decay_parameter[min_score_swap_qubits[0]], decay_parameter[min_score_swap_qubits[1]]) f_distance = 0 e_distance = 0 for gate_details in F: f_distance += calculate_distance(gate_details, distance_matrix, initial_mapping) for gate_details in E: e_distance += calculate_distance(gate_details, distance_matrix, initial_mapping) f_distance = f_distance / size_F e_distance = W * (e_distance / size_E) H = max_decay * (f_distance + e_distance) return H