Skip to content

Commit

Permalink
Fix explicitly calibrated gates in GateDirection (#9786)
Browse files Browse the repository at this point in the history
If there is an explicit calibration given, this overrides the generic
information from the `CouplingMap` or the `Target` for that particular
instance, since one can use pulse-level control to define gates on a
circuit-by-circuit basis that are not generically available in a way
that can be specified in the coupling or target.

(cherry picked from commit c2affb1)

# Conflicts:
#	test/python/transpiler/test_gate_direction.py
  • Loading branch information
jakelishman authored and mergify[bot] committed Mar 13, 2023
1 parent 881e0d9 commit bef3a13
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 0 deletions.
4 changes: 4 additions & 0 deletions qiskit/transpiler/passes/utils/gate_direction.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ def _run_coupling_map(self, dag, wire_map, edges=None):
continue
if len(node.qargs) != 2:
continue
if dag.has_calibration_for(node):
continue
qargs = (wire_map[node.qargs[0]], wire_map[node.qargs[1]])
if qargs not in edges and (qargs[1], qargs[0]) not in edges:
raise TranspilerError(
Expand Down Expand Up @@ -198,6 +200,8 @@ def _run_target(self, dag, wire_map):
continue
if len(node.qargs) != 2:
continue
if dag.has_calibration_for(node):
continue
qargs = (wire_map[node.qargs[0]], wire_map[node.qargs[1]])
swapped = (qargs[1], qargs[0])
if node.name in self._static_replacements:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
fixes:
- |
The :class:`.GateDirection` transpiler pass will no longer reject gates that have been given
explicit calibrations, but do not exist in the generic coupling map or target.
42 changes: 42 additions & 0 deletions test/python/transpiler/test_gate_direction.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,24 @@

import ddt

<<<<<<< HEAD
from qiskit import ClassicalRegister, QuantumRegister, QuantumCircuit
from qiskit.circuit import Parameter
from qiskit.circuit.library import CXGate, CZGate, ECRGate, RXXGate, RYYGate, RZXGate, RZZGate
=======
from qiskit import ClassicalRegister, QuantumRegister, QuantumCircuit, pulse
from qiskit.circuit import Parameter, Gate
from qiskit.circuit.library import (
CXGate,
CZGate,
ECRGate,
RXXGate,
RYYGate,
RZXGate,
RZZGate,
SwapGate,
)
>>>>>>> c2affb145 (Fix explicitly calibrated gates in `GateDirection` (#9786))
from qiskit.compiler import transpile
from qiskit.transpiler import TranspilerError, CouplingMap, Target
from qiskit.transpiler.passes import GateDirection
Expand Down Expand Up @@ -430,6 +445,33 @@ def test_target_control_flow(self):
pass_ = GateDirection(None, target)
self.assertEqual(pass_(circuit), expected)
def test_allows_calibrated_gates_coupling_map(self):
"""Test that the gate direction pass allows a gate that's got a calibration to pass through
without error."""
cm = CouplingMap([(1, 0)])
gate = Gate("my_2q_gate", 2, [])
circuit = QuantumCircuit(2)
circuit.append(gate, (0, 1))
circuit.add_calibration(gate, (0, 1), pulse.ScheduleBlock())
pass_ = GateDirection(cm)
self.assertEqual(pass_(circuit), circuit)
def test_allows_calibrated_gates_target(self):
"""Test that the gate direction pass allows a gate that's got a calibration to pass through
without error."""
target = Target(num_qubits=2)
target.add_instruction(CXGate(), properties={(0, 1): None})

gate = Gate("my_2q_gate", 2, [])
circuit = QuantumCircuit(2)
circuit.append(gate, (0, 1))
circuit.add_calibration(gate, (0, 1), pulse.ScheduleBlock())

pass_ = GateDirection(None, target)
self.assertEqual(pass_(circuit), circuit)


if __name__ == "__main__":
unittest.main()

0 comments on commit bef3a13

Please sign in to comment.