diff --git a/qiskit/transpiler/passes/utils/gate_direction.py b/qiskit/transpiler/passes/utils/gate_direction.py index 12cb4ecdcf01..323f19bf7fe9 100644 --- a/qiskit/transpiler/passes/utils/gate_direction.py +++ b/qiskit/transpiler/passes/utils/gate_direction.py @@ -166,6 +166,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( @@ -209,6 +211,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: diff --git a/releasenotes/notes/fix-gate-direction-calibration-c51202358d86e18f.yaml b/releasenotes/notes/fix-gate-direction-calibration-c51202358d86e18f.yaml new file mode 100644 index 000000000000..140ff5b71028 --- /dev/null +++ b/releasenotes/notes/fix-gate-direction-calibration-c51202358d86e18f.yaml @@ -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. diff --git a/test/python/transpiler/test_gate_direction.py b/test/python/transpiler/test_gate_direction.py index 3ccb5aa958f4..06c1d814b147 100644 --- a/test/python/transpiler/test_gate_direction.py +++ b/test/python/transpiler/test_gate_direction.py @@ -17,8 +17,8 @@ import ddt -from qiskit import ClassicalRegister, QuantumRegister, QuantumCircuit -from qiskit.circuit import Parameter +from qiskit import ClassicalRegister, QuantumRegister, QuantumCircuit, pulse +from qiskit.circuit import Parameter, Gate from qiskit.circuit.library import ( CXGate, CZGate, @@ -439,6 +439,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()