- class Commuting2qGateRouter(swap_strategy=None, edge_coloring=None)[source]¶
A class to swap route one or more commuting gates to the coupling map.
This pass routes blocks of commuting two-qubit gates encapsulated as
Commuting2qBlockinstructions. This pass will not apply to other instructions. The mapping to the coupling map is done using swap strategies, see
SwapStrategy. The swap strategy should suit the problem and the coupling map. This transpiler pass should ideally be executed before the quantum circuit is enlarged with any idle ancilla qubits. Otherwise we may swap qubits outside of the portion of the chip we want to use. Therefore, the swap strategy and its associated coupling map do not represent physical qubits. Instead, they represent an intermediate mapping that corresponds to the physical qubits once the initial layout is applied. The example below shows how to map a four qubit
PauliEvolutionGateto qubits 0, 1, 3, and 4 of the five qubit device with the coupling map
0 -- 1 -- 2 | 3 | 4
To do this we use a line swap strategy for qubits 0, 1, 3, and 4 defined it in terms of virtual qubits 0, 1, 2, and 3.
from qiskit import QuantumCircuit from qiskit.opflow import PauliSumOp from qiskit.circuit.library import PauliEvolutionGate from qiskit.transpiler import Layout, CouplingMap, PassManager from qiskit.transpiler.passes import FullAncillaAllocation from qiskit.transpiler.passes import EnlargeWithAncilla from qiskit.transpiler.passes import ApplyLayout from qiskit.transpiler.passes import SetLayout from qiskit.transpiler.passes.routing.commuting_2q_gate_routing import ( SwapStrategy, FindCommutingPauliEvolutions, Commuting2qGateRouter, ) # Define the circuit on virtual qubits op = PauliSumOp.from_list([("IZZI", 1), ("ZIIZ", 2), ("ZIZI", 3)]) circ = QuantumCircuit(4) circ.append(PauliEvolutionGate(op, 1), range(4)) # Define the swap strategy on qubits before the initial_layout is applied. swap_strat = SwapStrategy.from_line([0, 1, 2, 3]) # Chose qubits 0, 1, 3, and 4 from the backend coupling map shown above. backend_cmap = CouplingMap(couplinglist=[(0, 1), (1, 2), (1, 3), (3, 4)]) initial_layout = Layout.from_intlist([0, 1, 3, 4], *circ.qregs) pm_pre = PassManager( [ FindCommutingPauliEvolutions(), Commuting2qGateRouter(swap_strat), SetLayout(initial_layout), FullAncillaAllocation(backend_cmap), EnlargeWithAncilla(), ApplyLayout(), ] ) # Insert swap gates, map to initial_layout and finally enlarge with ancilla. pm_pre.run(circ).draw("mpl")
This pass manager relies on the
current_layoutwhich corresponds to the qubit layout as swap gates are applied. The pass will traverse all nodes in the dag. If a node should be routed using a swap strategy then it will be decomposed into sub-instructions with swap layers in between and the
current_layoutwill be modified. Nodes that should not be routed using swap strategies will be added back to the dag taking the
SwapStrategy]) – An instance of a
SwapStrategythat holds the swap layers that are used, and the order in which to apply them, to map the instruction to the hardware. If this field is not given if should be contained in the property set of the pass. This allows other passes to determine the most appropriate swap strategy at run-time.
int]]) – An optional edge coloring of the coupling map (I.e. no two edges that share a node have the same color). If the edge coloring is given then the commuting gates that can be simultaneously applied given the current qubit permutation are grouped according to the edge coloring and applied according to this edge coloring. Here, a color is an int which is used as the index to define and access the groups of commuting gates that can be applied simultaneously. If the edge coloring is not given then the sets will be built-up using a greedy algorithm. The edge coloring is useful to position gates such as
RZZGates next to swap gates to exploit CX cancellations.
Return the name of the pass.
Run the pass by decomposing the nodes it applies on.
Take an instance of
Commuting2qBlockand map it to the coupling map.
Check if the pass is an analysis pass.
If the pass is an AnalysisPass, that means that the pass can analyze the DAG and write the results of that analysis in the property set. Modifications on the DAG are not allowed by this kind of pass.
Check if the pass is a transformation pass.
If the pass is a TransformationPass, that means that the pass can manipulate the DAG, but cannot modify the property set (but it can be read).