Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions qiskit/circuit/quantumcircuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -441,21 +441,26 @@ def calibrations(self, calibrations: dict):
"""
self._calibrations = defaultdict(dict, calibrations)

def has_calibration_for(self, instruction: CircuitInstruction):
def has_calibration_for(self, instruction: CircuitInstruction | tuple):
"""Return True if the circuit has a calibration defined for the instruction context. In this
case, the operation does not need to be translated to the device basis.
"""
if not self.calibrations or instruction.operation.name not in self.calibrations:
if isinstance(instruction, CircuitInstruction):
operation = instruction.operation
qubits = instruction.qubits
else:
operation, qubits, _ = instruction
if not self.calibrations or operation.name not in self.calibrations:
return False
qubits = tuple(self.qubits.index(qubit) for qubit in instruction.qubits)
qubits = tuple(self.qubits.index(qubit) for qubit in qubits)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this use find bits? It's the same as before so I'm fine merging it as is, but I just worry the performance of this is pretty poor. Although I guess the number of qubits for a gate won't be that wide so it's probably not a big deal.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it probably should - this is doing unnecessary linear searches now. I think there's a few places throughout Qiskit where we're doing list.index, and they're pretty much all potential performance problems.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well lets do all of them in a single pass, the performance here isn't critical for this PR, it's more to fix the api breakage.

params = []
for p in instruction.operation.params:
for p in operation.params:
if isinstance(p, ParameterExpression) and not p.parameters:
params.append(float(p))
else:
params.append(p)
params = tuple(params)
return (qubits, params) in self.calibrations[instruction.operation.name]
return (qubits, params) in self.calibrations[operation.name]

@property
def metadata(self) -> dict:
Expand Down
37 changes: 37 additions & 0 deletions test/python/circuit/test_circuit_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -1255,6 +1255,43 @@ def test_calibrations_no_params(self):
self.assertEqual(set(circ.calibrations["h"].keys()), {((0,), ())})
self.assertEqual(circ.calibrations["h"][((0,), ())].instructions, q0_x180.instructions)

def test_has_calibration_for(self):
"""Test that `has_calibration_for` returns a correct answer."""
qc = QuantumCircuit(3)

with pulse.build() as q0_x180:
pulse.play(pulse.library.Gaussian(20, 1.0, 3.0), pulse.DriveChannel(0))
qc.add_calibration("h", [0], q0_x180)

qc.h(0)
qc.h(1)

self.assertTrue(qc.has_calibration_for(qc.data[0]))
self.assertFalse(qc.has_calibration_for(qc.data[1]))

def test_has_calibration_for_legacy(self):
"""Test that `has_calibration_for` returns a correct answer when presented with a legacy 3
tuple."""
qc = QuantumCircuit(3)

with pulse.build() as q0_x180:
pulse.play(pulse.library.Gaussian(20, 1.0, 3.0), pulse.DriveChannel(0))
qc.add_calibration("h", [0], q0_x180)

qc.h(0)
qc.h(1)

self.assertTrue(
qc.has_calibration_for(
(qc.data[0].operation, list(qc.data[0].qubits), list(qc.data[0].clbits))
)
)
self.assertFalse(
qc.has_calibration_for(
(qc.data[1].operation, list(qc.data[1].qubits), list(qc.data[1].clbits))
)
)

def test_metadata_copy_does_not_share_state(self):
"""Verify mutating the metadata of a circuit copy does not impact original."""
# ref: https://github.com/Qiskit/qiskit-terra/issues/6057
Expand Down