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.
  • Loading branch information
jakelishman committed Mar 13, 2023
1 parent 881e0d9 commit 549e4c6
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 2 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.
31 changes: 29 additions & 2 deletions test/python/transpiler/test_gate_direction.py
Original file line number Diff line number Diff line change
Expand Up @@ -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, ECRGate, RXXGate, RYYGate, RZXGate, RZZGate
from qiskit.compiler import transpile
from qiskit.transpiler import TranspilerError, CouplingMap, Target
Expand Down Expand Up @@ -430,6 +430,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 549e4c6

Please sign in to comment.