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
3 changes: 2 additions & 1 deletion qiskit/transpiler/passes/calibration/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@

"""Module containing transpiler calibration passes."""

from .builders import RZXCalibrationBuilder, RZXCalibrationBuilderNoEcho, PulseGates
from .pulse_gate import PulseGates
from .rzx_builder import RZXCalibrationBuilder, RZXCalibrationBuilderNoEcho
80 changes: 80 additions & 0 deletions qiskit/transpiler/passes/calibration/base_builder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2022.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Calibration builder base class."""

from abc import abstractmethod
from typing import List, Union

from qiskit.circuit import Instruction as CircuitInst
from qiskit.dagcircuit import DAGCircuit
from qiskit.pulse import Schedule, ScheduleBlock
from qiskit.pulse.instruction_schedule_map import CalibrationPublisher
from qiskit.transpiler.basepasses import TransformationPass

from .exceptions import CalibrationNotAvailable


class CalibrationBuilder(TransformationPass):
"""Abstract base class to inject calibrations into circuits."""

@abstractmethod
def supported(self, node_op: CircuitInst, qubits: List) -> bool:
"""Determine if a given node supports the calibration.

Args:
node_op: Target instruction object.
qubits: Integer qubit indices to check.

Returns:
Return ``True`` is calibration can be provided.
"""

@abstractmethod
def get_calibration(self, node_op: CircuitInst, qubits: List) -> Union[Schedule, ScheduleBlock]:
"""Gets the calibrated schedule for the given instruction and qubits.

Args:
node_op: Target instruction object.
qubits: Integer qubit indices to check.

Returns:
Return Schedule of target gate instruction.
"""

def run(self, dag: DAGCircuit) -> DAGCircuit:
"""Run the calibration adder pass on `dag`.

Args:
dag: DAG to schedule.

Returns:
A DAG with calibrations added to it.
"""
qubit_map = {qubit: i for i, qubit in enumerate(dag.qubits)}
for node in dag.gate_nodes():
qubits = [qubit_map[q] for q in node.qargs]

if self.supported(node.op, qubits) and not dag.has_calibration_for(node):
# calibration can be provided and no user-defined calibration is already provided
try:
schedule = self.get_calibration(node.op, qubits)
except CalibrationNotAvailable:
# Fail in schedule generation. Just ignore.
continue
publisher = schedule.metadata.get("publisher", CalibrationPublisher.QISKIT)

# add calibration if it is not backend default
if publisher != CalibrationPublisher.BACKEND_PROVIDER:
dag.add_calibration(gate=node.op, qubits=qubits, schedule=schedule)

return dag
Loading