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 authored Mar 13, 2023
1 parent 2ce129a commit c2affb1
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 @@ -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(
Expand Down Expand Up @@ -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:
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,
Expand Down Expand Up @@ -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()

0 comments on commit c2affb1

Please sign in to comment.