def run(self, dag): """ If `dag` is mapped and the direction is correct the property `is_direction_mapped` is set to True (or to False otherwise). Args: dag (DAGCircuit): DAG to map. """ if self.layout is None: if self.property_set["layout"]: self.layout = self.property_set["layout"] else: self.layout = Layout.generate_trivial_layout(*dag.qregs.values()) self.property_set['is_direction_mapped'] = True edges = self.coupling_map.get_edges() for gate in dag.twoQ_gates(): physical_q0 = self.layout[gate['qargs'][0]] physical_q1 = self.layout[gate['qargs'][1]] if isinstance(gate['op'], (CXBase, CnotGate)) and ( physical_q0, physical_q1) not in edges: self.property_set['is_direction_mapped'] = False return
def run(self, dag): """ Run the StochasticSwap pass on `dag`. Args: dag (DAGCircuit): DAG to map. Returns: DAGCircuit: A mapped DAG. Raises: TranspilerError: if the coupling map or the layout are not compatible with the DAG """ if self.initial_layout is None: if self.property_set["layout"]: self.initial_layout = self.property_set["layout"] else: self.initial_layout = Layout.generate_trivial_layout(*dag.qregs.values()) if len(dag.qubits()) != len(self.initial_layout): raise TranspilerError('The layout does not match the amount of qubits in the DAG') if len(self.coupling_map.physical_qubits) != len(self.initial_layout): raise TranspilerError( "Mappers require to have the layout to be the same size as the coupling map") self.input_layout = self.initial_layout.copy() new_dag = self._mapper(dag, self.coupling_map, trials=self.trials, seed=self.seed) # self.property_set["layout"] = self.initial_layout return new_dag
def run(self, dag): """ Run the StochasticSwap pass on `dag`. Args: dag (DAGCircuit): DAG to map. Returns: DAGCircuit: A mapped DAG. """ if self.initial_layout is None: if self.property_set["layout"]: self.initial_layout = self.property_set["layout"] else: self.initial_layout = Layout.generate_trivial_layout( *dag.qregs.values()) self.input_layout = self.initial_layout.copy() new_dag = self._mapper(dag, self.coupling_map, trials=self.trials, seed=self.seed) # self.property_set["layout"] = self.initial_layout return new_dag
def run(self, dag): """ Flips the cx nodes to match the directed coupling map. Args: dag (DAGCircuit): DAG to map. Returns: DAGCircuit: The rearranged dag for the coupling map Raises: TranspilerError: If the circuit cannot be mapped just by flipping the cx nodes. """ new_dag = DAGCircuit() if self.layout is None: if self.property_set["layout"]: self.layout = self.property_set["layout"] else: self.layout = Layout.generate_trivial_layout( *dag.qregs.values()) for layer in dag.serial_layers(): subdag = layer['graph'] for cnot_id in subdag.get_named_nodes('cx', 'CX'): cnot_node = subdag.multi_graph.nodes[cnot_id] control = cnot_node['op'].qargs[0] target = cnot_node['op'].qargs[1] physical_q0 = self.layout[control] physical_q1 = self.layout[target] if self.coupling_map.distance(physical_q0, physical_q1) != 1: raise TranspilerError( 'The circuit requires a connection between physical ' 'qubits %s and %s' % (physical_q0, physical_q1)) if (physical_q0, physical_q1) not in self.coupling_map.get_edges(): # A flip needs to be done # Create the involved registers if control[0] not in subdag.qregs.values(): subdag.add_qreg(control[0]) if target[0] not in subdag.qregs.values(): subdag.add_qreg(target[0]) # Add H gates around subdag.add_basis_element('h', 1, 0, 0) subdag.apply_operation_back(HGate(target)) subdag.apply_operation_back(HGate(control)) subdag.apply_operation_front(HGate(target)) subdag.apply_operation_front(HGate(control)) # Flips the CX cnot_node['op'].qargs[0], cnot_node['op'].qargs[ 1] = target, control new_dag.extend_back(subdag) return new_dag
def run(self, dag): """ Runs the BasicSwap pass on `dag`. Args: dag (DAGCircuit): DAG to map. Returns: DAGCircuit: A mapped DAG. """ new_dag = DAGCircuit() if self.initial_layout is None: if self.property_set["layout"]: self.initial_layout = self.property_set["layout"] else: self.initial_layout = Layout.generate_trivial_layout(*dag.qregs.values()) current_layout = copy(self.initial_layout) for layer in dag.serial_layers(): subdag = layer['graph'] for gate in subdag.get_2q_nodes(): physical_q0 = current_layout[gate['qargs'][0]] physical_q1 = current_layout[gate['qargs'][1]] if self.coupling_map.distance(physical_q0, physical_q1) != 1: # Insert a new layer with the SWAP(s). swap_layer = DAGCircuit() path = self.coupling_map.shortest_undirected_path(physical_q0, physical_q1) for swap in range(len(path) - 2): connected_wire_1 = path[swap] connected_wire_2 = path[swap + 1] qubit_1 = current_layout[connected_wire_1] qubit_2 = current_layout[connected_wire_2] # create qregs for qreg in current_layout.get_registers(): if qreg[0] not in swap_layer.qregs.values(): swap_layer.add_qreg(qreg[0]) # create the swap operation swap_layer.add_basis_element('swap', 2, 0, 0) swap_layer.apply_operation_back(self.swap_gate(qubit_1, qubit_2), qargs=[qubit_1, qubit_2]) # layer insertion edge_map = current_layout.combine_into_edge_map(self.initial_layout) new_dag.compose_back(swap_layer, edge_map) # update current_layout for swap in range(len(path) - 2): current_layout.swap(path[swap], path[swap + 1]) edge_map = current_layout.combine_into_edge_map(self.initial_layout) new_dag.extend_back(subdag, edge_map) return new_dag
def test_final_measurement_barrier_for_devices(self, mock_pass): """Verify BarrierBeforeFinalMeasurements pass is called in default pipeline for devices.""" circ = QuantumCircuit.from_qasm_file(self._get_resource_path('example.qasm', Path.QASMS)) dag_circuit = circuit_to_dag(circ) layout = Layout.generate_trivial_layout(*circ.qregs) transpile_dag(dag_circuit, coupling_map=FakeRueschlikon().configuration().coupling_map, initial_layout=layout) self.assertTrue(mock_pass.called)
def test_default_layout(self): """Static method generate_trivial_layout creates a Layout""" qr0 = QuantumRegister(3, 'q0') qr1 = QuantumRegister(2, 'q1') layout = Layout.generate_trivial_layout(qr0, qr1) self.assertEqual(layout[(qr0, 0)], 0) self.assertEqual(layout[(qr0, 1)], 1) self.assertEqual(layout[(qr0, 2)], 2) self.assertEqual(layout[(qr1, 0)], 3) self.assertEqual(layout[(qr1, 1)], 4)
def run(self, dag): """Run one pass of the lookahead mapper on the provided DAG. Args: dag (DAGCircuit): the directed acyclic graph to be mapped Returns: DAGCircuit: A dag mapped to be compatible with the coupling_map in the property_set. Raises: TranspilerError: if the coupling map or the layout are not compatible with the DAG """ coupling_map = self._coupling_map ordered_virtual_gates = list(dag.serial_layers()) if self.initial_layout is None: if self.property_set["layout"]: self.initial_layout = self.property_set["layout"] else: self.initial_layout = Layout.generate_trivial_layout( *dag.qregs.values()) if len(dag.qubits()) != len(self.initial_layout): raise TranspilerError( 'The layout does not match the amount of qubits in the DAG') if len(self._coupling_map.physical_qubits) != len(self.initial_layout): raise TranspilerError( "Mappers require to have the layout to be the same size as the coupling map" ) mapped_gates = [] layout = self.initial_layout.copy() gates_remaining = ordered_virtual_gates.copy() while gates_remaining: best_step = _search_forward_n_swaps(layout, gates_remaining, coupling_map) layout = best_step['layout'] gates_mapped = best_step['gates_mapped'] gates_remaining = best_step['gates_remaining'] mapped_gates.extend(gates_mapped) # Preserve input DAG's name, regs, wire_map, etc. but replace the graph. mapped_dag = _copy_circuit_metadata(dag, coupling_map) for node in mapped_gates: mapped_dag.apply_operation_back(op=node.op, qargs=node.qargs, cargs=node.cargs) return mapped_dag
def run(self, dag): """ Pick a layout by assigning n circuit qubits to device qubits 0, .., n-1. Args: dag (DAGCircuit): DAG to find layout for. Raises: TranspilerError: if dag wider than self.coupling_map """ num_dag_qubits = sum([qreg.size for qreg in dag.qregs.values()]) if num_dag_qubits > self.coupling_map.size(): raise TranspilerError('Number of qubits greater than device.') self.property_set['layout'] = Layout.generate_trivial_layout(*dag.qregs.values())
def run(self, dag): """Run one pass of the lookahead mapper on the provided DAG. Args: dag (DAGCircuit): the directed acyclic graph to be mapped Returns: DAGCircuit: A dag mapped to be compatible with the coupling_map in the property_set. Raises: TranspilerError: If the provided DAG has more qubits than are available in the coupling map. """ coupling_map = self._coupling_map ordered_virtual_gates = list(dag.serial_layers()) if len(dag.get_qubits()) > len(coupling_map.physical_qubits): raise TranspilerError('DAG contains more qubits than are ' 'present in the coupling map.') if self.initial_layout is None: if self.property_set["layout"]: self.initial_layout = self.property_set["layout"] else: self.initial_layout = Layout.generate_trivial_layout( *dag.qregs.values()) mapped_gates = [] layout = self.initial_layout.copy() gates_remaining = ordered_virtual_gates.copy() while gates_remaining: best_step = _search_forward_n_swaps(layout, gates_remaining, coupling_map) layout = best_step['layout'] gates_mapped = best_step['gates_mapped'] gates_remaining = best_step['gates_remaining'] mapped_gates.extend(gates_mapped) # Preserve input DAG's name, regs, wire_map, etc. but replace the graph. mapped_dag = _copy_circuit_metadata(dag, coupling_map) for gate in mapped_gates: mapped_dag.apply_operation_back(**gate) return mapped_dag
def run(self, dag): """ If `dag` is mapped to `coupling_map`, the property `is_swap_mapped` is set to True (or to False otherwise). Args: dag (DAGCircuit): DAG to map. """ if self.layout is None: if self.property_set["layout"]: self.layout = self.property_set["layout"] else: self.layout = Layout.generate_trivial_layout(*dag.qregs.values()) self.property_set['is_swap_mapped'] = True for gate in dag.twoQ_nodes(): physical_q0 = self.layout[gate['qargs'][0]] physical_q1 = self.layout[gate['qargs'][1]] if self.coupling_map.distance(physical_q0, physical_q1) != 1: self.property_set['is_swap_mapped'] = False return
def run(self, dag): """ If `dag` is mapped to `coupling_map`, the property `is_swap_mapped` is set to True (or to False otherwise). If `dag` is mapped and the direction is correct the property `is_direction_mapped` is set to True (or to False otherwise). Args: dag (DAGCircuit): DAG to map. """ if self.layout is None: if self.property_set["layout"]: self.layout = self.property_set["layout"] else: self.layout = Layout.generate_trivial_layout( *dag.qregs.values()) self.property_set['is_swap_mapped'] = True self.property_set['is_direction_mapped'] = True for gate in dag.get_2q_nodes(): physical_q0 = self.layout[gate['qargs'][0]] physical_q1 = self.layout[gate['qargs'][1]] if self.coupling_map.distance(physical_q0, physical_q1) != 1: self.property_set['is_swap_mapped'] = False self.property_set['is_direction_mapped'] = False return else: if (physical_q0, physical_q1) not in self.coupling_map.get_edges(): self.property_set['is_direction_mapped'] = False if isinstance(gate['op'], SwapGate): if (physical_q1, physical_q0) not in self.coupling_map.get_edges(): self.property_set['is_direction_mapped'] = False
def run(self, dag): """ Runs the BasicSwap pass on `dag`. Args: dag (DAGCircuit): DAG to map. Returns: DAGCircuit: A mapped DAG. Raises: TranspilerError: if the coupling map or the layout are not compatible with the DAG """ new_dag = DAGCircuit() if self.initial_layout is None: if self.property_set["layout"]: self.initial_layout = self.property_set["layout"] else: self.initial_layout = Layout.generate_trivial_layout(*dag.qregs.values()) if len(dag.qubits()) != len(self.initial_layout): raise TranspilerError('The layout does not match the amount of qubits in the DAG') if len(self.coupling_map.physical_qubits) != len(self.initial_layout): raise TranspilerError( "Mappers require to have the layout to be the same size as the coupling map") current_layout = self.initial_layout.copy() for layer in dag.serial_layers(): subdag = layer['graph'] for gate in subdag.twoQ_gates(): physical_q0 = current_layout[gate.qargs[0]] physical_q1 = current_layout[gate.qargs[1]] if self.coupling_map.distance(physical_q0, physical_q1) != 1: # Insert a new layer with the SWAP(s). swap_layer = DAGCircuit() path = self.coupling_map.shortest_undirected_path(physical_q0, physical_q1) for swap in range(len(path) - 2): connected_wire_1 = path[swap] connected_wire_2 = path[swap + 1] qubit_1 = current_layout[connected_wire_1] qubit_2 = current_layout[connected_wire_2] # create qregs for qreg in current_layout.get_registers(): if qreg not in swap_layer.qregs.values(): swap_layer.add_qreg(qreg) # create the swap operation swap_layer.apply_operation_back(SwapGate(), qargs=[qubit_1, qubit_2], cargs=[]) # layer insertion edge_map = current_layout.combine_into_edge_map(self.initial_layout) new_dag.compose_back(swap_layer, edge_map) # update current_layout for swap in range(len(path) - 2): current_layout.swap(path[swap], path[swap + 1]) edge_map = current_layout.combine_into_edge_map(self.initial_layout) new_dag.extend_back(subdag, edge_map) return new_dag