From f1d023e13ac052f9320897bb6226ec1ae6cd031a Mon Sep 17 00:00:00 2001 From: Vaibhaw Kumar Date: Mon, 12 Jul 2021 16:56:32 -0400 Subject: [PATCH 1/8] adding edits to resolve issue 6079 --- qiskit/transpiler/passes/__init__.py | 9 +- .../transpiler/passes/scheduling/__init__.py | 2 - .../passes/transformation/__init__.py | 16 + .../transformation/calibration_creators.py | 377 ++++++++++++++++++ .../passes/transformation/rzx_templates.py | 49 +++ 5 files changed, 449 insertions(+), 4 deletions(-) create mode 100644 qiskit/transpiler/passes/transformation/__init__.py create mode 100644 qiskit/transpiler/passes/transformation/calibration_creators.py create mode 100644 qiskit/transpiler/passes/transformation/rzx_templates.py diff --git a/qiskit/transpiler/passes/__init__.py b/qiskit/transpiler/passes/__init__.py index ba1e39796755..f9fb19f63498 100644 --- a/qiskit/transpiler/passes/__init__.py +++ b/qiskit/transpiler/passes/__init__.py @@ -88,7 +88,10 @@ DynamicalDecoupling AlignMeasures ValidatePulseGates - RZXCalibrationBuilder + +Transformation +================= +RZXCalibrationBuilder Circuit Analysis ================ @@ -193,7 +196,9 @@ from .scheduling import DynamicalDecoupling from .scheduling import AlignMeasures from .scheduling import ValidatePulseGates -from .scheduling import RZXCalibrationBuilder + +# circuit transformation +from .transformation import RZXCalibrationBuilder # additional utility passes from .utils import CheckMap diff --git a/qiskit/transpiler/passes/scheduling/__init__.py b/qiskit/transpiler/passes/scheduling/__init__.py index ea8f8e3456a1..f8270d23da54 100644 --- a/qiskit/transpiler/passes/scheduling/__init__.py +++ b/qiskit/transpiler/passes/scheduling/__init__.py @@ -16,6 +16,4 @@ from .asap import ASAPSchedule from .time_unit_conversion import TimeUnitConversion from .dynamical_decoupling import DynamicalDecoupling -from .calibration_creators import CalibrationCreator, RZXCalibrationBuilder -from .rzx_templates import rzx_templates from .instruction_alignment import AlignMeasures, ValidatePulseGates diff --git a/qiskit/transpiler/passes/transformation/__init__.py b/qiskit/transpiler/passes/transformation/__init__.py new file mode 100644 index 000000000000..d5103a4e4483 --- /dev/null +++ b/qiskit/transpiler/passes/transformation/__init__.py @@ -0,0 +1,16 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 2020. +# +# 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. + +"""Module containing circuit transformation passes.""" + +from .calibration_creators import CalibrationCreator, RZXCalibrationBuilder +from .rzx_templates import rzx_templates diff --git a/qiskit/transpiler/passes/transformation/calibration_creators.py b/qiskit/transpiler/passes/transformation/calibration_creators.py new file mode 100644 index 000000000000..5b44e9cffbf5 --- /dev/null +++ b/qiskit/transpiler/passes/transformation/calibration_creators.py @@ -0,0 +1,377 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 2021. +# +# 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 creators.""" + +import math +from typing import List, Union +from abc import abstractmethod +import numpy as np + +from qiskit.pulse import ( + Play, + Delay, + ShiftPhase, + Schedule, + ControlChannel, + DriveChannel, + GaussianSquare, +) +from qiskit.pulse.instructions.instruction import Instruction +from qiskit.exceptions import QiskitError +from qiskit.providers import basebackend +from qiskit.dagcircuit import DAGNode +from qiskit.circuit.library.standard_gates import RZXGate +from qiskit.transpiler.basepasses import TransformationPass + + +class CalibrationCreator(TransformationPass): + """Abstract base class to inject calibrations into circuits.""" + + @abstractmethod + def supported(self, node_op: DAGNode) -> bool: + """Determine if a given name supports the calibration.""" + + @abstractmethod + def get_calibration(self, params: List, qubits: List) -> Schedule: + """Gets the calibrated schedule for the given qubits and parameters.""" + + def run(self, dag): + """Run the calibration adder pass on `dag`. + + Args: + dag (DAGCircuit): DAG to schedule. + + Returns: + DAGCircuit: A DAG with calibrations added to it. + """ + bit_indices = {bit: index for index, bit in enumerate(dag.qubits)} + + for node in dag.nodes(): + if node.type == "op": + if self.supported(node.op): + params = node.op.params + qubits = [bit_indices[qarg] for qarg in node.qargs] + + schedule = self.get_calibration(params, qubits) + + dag.add_calibration(node.op, qubits, schedule, params=params) + + return dag + + +class RZXCalibrationBuilder(CalibrationCreator): + """ + Creates calibrations for RZXGate(theta) by stretching and compressing + Gaussian square pulses in the CX gate. This is done by retrieving (for a given pair of + qubits) the CX schedule in the instruction schedule map of the backend defaults. + The CX schedule must be an echoed cross-resonance gate optionally with rotary tones. + The cross-resonance drive tones and rotary pulses must be Gaussian square pulses. + The width of the Gaussian square pulse is adjusted so as to match the desired rotation angle. + If the rotation angle is small such that the width disappears then the amplitude of the + zero width Gaussian square pulse (i.e. a Gaussian) is reduced to reach the target rotation + angle. Additional details can be found in https://arxiv.org/abs/2012.11660. + """ + + def __init__(self, backend: basebackend): + """ + Initializes a RZXGate calibration builder. + + Args: + backend: Backend for which to construct the gates. + + Raises: + QiskitError: if open pulse is not supported by the backend. + """ + super().__init__() + if not backend.configuration().open_pulse: + raise QiskitError( + "Calibrations can only be added to Pulse-enabled backends, " + "but {} is not enabled with Pulse.".format(backend.name()) + ) + + self._inst_map = backend.defaults().instruction_schedule_map + self._config = backend.configuration() + self._channel_map = backend.configuration().qubit_channel_mapping + + def supported(self, node_op: DAGNode) -> bool: + """ + Args: + node_op: The node from the dag dep. + + Returns: + match: True if the node is a RZXGate. + """ + return isinstance(node_op, RZXGate) + + @staticmethod + def rescale_cr_inst(instruction: Play, theta: float, sample_mult: int = 16) -> Play: + """ + Args: + instruction: The instruction from which to create a new shortened or lengthened pulse. + theta: desired angle, pi/2 is assumed to be the angle that the pulse in the given + play instruction implements. + sample_mult: All pulses must be a multiple of sample_mult. + + Returns: + qiskit.pulse.Play: The play instruction with the stretched compressed + GaussianSquare pulse. + + Raises: + QiskitError: if the pulses are not GaussianSquare. + """ + pulse_ = instruction.pulse + if isinstance(pulse_, GaussianSquare): + amp = pulse_.amp + width = pulse_.width + sigma = pulse_.sigma + n_sigmas = (pulse_.duration - width) / sigma + + # The error function is used because the Gaussian may have chopped tails. + gaussian_area = abs(amp) * sigma * np.sqrt(2 * np.pi) * math.erf(n_sigmas) + area = gaussian_area + abs(amp) * width + + target_area = abs(theta) / (np.pi / 2.0) * area + sign = theta / abs(theta) + + if target_area > gaussian_area: + width = (target_area - gaussian_area) / abs(amp) + duration = math.ceil((width + n_sigmas * sigma) / sample_mult) * sample_mult + return Play( + GaussianSquare(amp=sign * amp, width=width, sigma=sigma, duration=duration), + channel=instruction.channel, + ) + else: + amp_scale = sign * target_area / gaussian_area + duration = math.ceil(n_sigmas * sigma / sample_mult) * sample_mult + return Play( + GaussianSquare(amp=amp * amp_scale, width=0, sigma=sigma, duration=duration), + channel=instruction.channel, + ) + else: + raise QiskitError("RZXCalibrationBuilder only stretches/compresses GaussianSquare.") + + def get_calibration(self, params: List, qubits: List) -> Schedule: + """ + Args: + params: Parameters of the RZXGate(theta). I.e. params[0] is theta. + qubits: List of qubits for which to get the schedules. The first qubit is + the control and the second is the target. + + Returns: + schedule: The calibration schedule for the RZXGate(theta). + + Raises: + QiskitError: if the control and target qubits cannot be identified or the backend + does not support cx between the qubits. + """ + theta = params[0] + q1, q2 = qubits[0], qubits[1] + + if not self._inst_map.has("cx", qubits): + raise QiskitError( + "This transpilation pass requires the backend to support cx " + "between qubits %i and %i." % (q1, q2) + ) + + cx_sched = self._inst_map.get("cx", qubits=(q1, q2)) + rzx_theta = Schedule(name="rzx(%.3f)" % theta) + + if theta == 0.0: + return rzx_theta + + crs, comp_tones = [], [] + control, target = None, None + + for time, inst in cx_sched.instructions: + + # Identify the CR pulses. + if isinstance(inst, Play) and not isinstance(inst, ShiftPhase): + if isinstance(inst.channel, ControlChannel): + crs.append((time, inst)) + + # Identify the compensation tones. + if isinstance(inst.channel, DriveChannel) and not isinstance(inst, ShiftPhase): + if isinstance(inst.pulse, GaussianSquare): + comp_tones.append((time, inst)) + target = inst.channel.index + control = q1 if target == q2 else q2 + + if control is None: + raise QiskitError("Control qubit is None.") + if target is None: + raise QiskitError("Target qubit is None.") + + echo_x = self._inst_map.get("x", qubits=control) + + # Build the schedule + + # Stretch/compress the CR gates and compensation tones + cr1 = self.rescale_cr_inst(crs[0][1], theta) + cr2 = self.rescale_cr_inst(crs[1][1], theta) + + if len(comp_tones) == 0: + comp1, comp2 = None, None + elif len(comp_tones) == 2: + comp1 = self.rescale_cr_inst(comp_tones[0][1], theta) + comp2 = self.rescale_cr_inst(comp_tones[1][1], theta) + else: + raise QiskitError( + "CX must have either 0 or 2 rotary tones between qubits %i and %i " + "but %i were found." % (control, target, len(comp_tones)) + ) + + # Build the schedule for the RZXGate + rzx_theta = rzx_theta.insert(0, cr1) + + if comp1 is not None: + rzx_theta = rzx_theta.insert(0, comp1) + + rzx_theta = rzx_theta.insert(comp1.duration, echo_x) + time = comp1.duration + echo_x.duration + rzx_theta = rzx_theta.insert(time, cr2) + + if comp2 is not None: + rzx_theta = rzx_theta.insert(time, comp2) + + time = 2 * comp1.duration + echo_x.duration + rzx_theta = rzx_theta.insert(time, echo_x) + + # Reverse direction of the ZX with Hadamard gates + if control == qubits[0]: + return rzx_theta + else: + rzc = self._inst_map.get("rz", [control], np.pi / 2) + sxc = self._inst_map.get("sx", [control]) + rzt = self._inst_map.get("rz", [target], np.pi / 2) + sxt = self._inst_map.get("sx", [target]) + h_sched = Schedule(name="hadamards") + h_sched = h_sched.insert(0, rzc) + h_sched = h_sched.insert(0, sxc) + h_sched = h_sched.insert(sxc.duration, rzc) + h_sched = h_sched.insert(0, rzt) + h_sched = h_sched.insert(0, sxt) + h_sched = h_sched.insert(sxc.duration, rzt) + rzx_theta = h_sched.append(rzx_theta) + return rzx_theta.append(h_sched) + + +class RZXCalibrationBuilderNoEcho(RZXCalibrationBuilder): + """ + Creates calibrations for RZXGate(theta) by stretching and compressing + Gaussian square pulses in the CX gate. + The RZXCalibrationBuilderNoEcho is a variation of the RZXCalibrationBuilder + as it creates calibrations for the cross-resonance pulses without inserting + the echo pulses in the pulse schedule. This enables exposing the echo in + the cross-resonance sequence as gates so that the transpiler can simplify them. + The RZXCalibrationBuilderNoEcho only supports the hardware-native direction + of the CX gate. + """ + + @staticmethod + def _filter_control(inst: (int, Union["Schedule", Instruction])) -> bool: + """ + Looks for Gaussian square pulses applied to control channels. + Args: + inst: Instructions to be filtered. + Returns: + match: True if the instruction is a Play instruction with + a Gaussian square pulse on the ControlChannel. + """ + if isinstance(inst[1], Play): + if isinstance(inst[1].pulse, GaussianSquare) and isinstance( + inst[1].channel, ControlChannel + ): + return True + + return False + + @staticmethod + def _filter_drive(inst: (int, Union["Schedule", Instruction])) -> bool: + """ + Looks for Gaussian square pulses applied to drive channels. + Args: + inst: Instructions to be filtered. + Returns: + match: True if the instruction is a Play instruction with + a Gaussian square pulse on the DriveChannel. + """ + if isinstance(inst[1], Play): + if isinstance(inst[1].pulse, GaussianSquare) and isinstance( + inst[1].channel, DriveChannel + ): + return True + + return False + + def get_calibration(self, params: List, qubits: List) -> Schedule: + """ + Builds the calibration schedule for the RZXGate(theta) without echos. + Args: + params: Parameters of the RZXGate(theta). I.e. params[0] is theta. + qubits: List of qubits for which to get the schedules. The first qubit is + the control and the second is the target. + Returns: + schedule: The calibration schedule for the RZXGate(theta). + Raises: + QiskitError: If the control and target qubits cannot be identified, or the backend + does not support a cx gate between the qubits, or the backend does not natively + support the specified direction of the cx. + """ + theta = params[0] + q1, q2 = qubits[0], qubits[1] + + if not self._inst_map.has("cx", qubits): + raise QiskitError( + "This transpilation pass requires the backend to support cx " + "between qubits %i and %i." % (q1, q2) + ) + + cx_sched = self._inst_map.get("cx", qubits=(q1, q2)) + rzx_theta = Schedule(name="rzx(%.3f)" % theta) + + if theta == 0.0: + return rzx_theta + + control, target = None, None + + for _, inst in cx_sched.instructions: + # Identify the compensation tones. + if isinstance(inst.channel, DriveChannel) and isinstance(inst, Play): + if isinstance(inst.pulse, GaussianSquare): + target = inst.channel.index + control = q1 if target == q2 else q2 + + if control is None: + raise QiskitError("Control qubit is None.") + if target is None: + raise QiskitError("Target qubit is None.") + + if control != qubits[0]: + raise QiskitError( + "RZXCalibrationBuilderNoEcho only supports hardware-native RZX gates." + ) + + # Get the filtered Schedule instructions for the CR gates and compensation tones. + crs = cx_sched.filter(*[self._filter_control]).instructions + rotaries = cx_sched.filter(*[self._filter_drive]).instructions + + # Stretch/compress the CR gates and compensation tones. + cr = self.rescale_cr_inst(crs[0][1], 2 * theta) + rot = self.rescale_cr_inst(rotaries[0][1], 2 * theta) + + # Build the schedule for the RZXGate without the echos. + rzx_theta = rzx_theta.insert(0, cr) + rzx_theta = rzx_theta.insert(0, rot) + rzx_theta = rzx_theta.insert(0, Delay(cr.duration, DriveChannel(control))) + + return rzx_theta diff --git a/qiskit/transpiler/passes/transformation/rzx_templates.py b/qiskit/transpiler/passes/transformation/rzx_templates.py new file mode 100644 index 000000000000..54a095d066df --- /dev/null +++ b/qiskit/transpiler/passes/transformation/rzx_templates.py @@ -0,0 +1,49 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 2021. +# +# 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. + +""" +Convenience function to load RZXGate based templates. +""" + +from typing import List + +from qiskit.circuit.library.templates.rzx import rzx_zz1, rzx_zz2, rzx_zz3, rzx_yz, rzx_xz, rzx_cy + + +def rzx_templates(template_list: List[str] = None): + """ + Convenience function to get the cost_dict and + templates for template matching. + """ + + if template_list is None: + template_list = ["zz1", "zz2", "zz3", "yz", "xz", "cy"] + + templates = [] + if "zz1" in template_list: + templates.append(rzx_zz1()) + if "zz2" in template_list: + templates.append(rzx_zz2()) + if "zz3" in template_list: + templates.append(rzx_zz3()) + if "yz" in template_list: + templates.append(rzx_yz()) + if "xz" in template_list: + templates.append(rzx_xz()) + if "cy" in template_list: + templates.append(rzx_cy()) + + cost_dict = {"rzx": 0, "cx": 6, "rz": 0, "sx": 1, "p": 0, "h": 1, "rx": 1, "ry": 1} + + rzx_dict = {"template_list": templates, "user_cost_dict": cost_dict} + + return rzx_dict From e8cf7fc3d4e228d57fb19800831a07b915a694b8 Mon Sep 17 00:00:00 2001 From: amitracal Date: Mon, 12 Jul 2021 14:25:55 -0700 Subject: [PATCH 2/8] Edited test file --- test/python/pulse/test_calibrationbuilder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/python/pulse/test_calibrationbuilder.py b/test/python/pulse/test_calibrationbuilder.py index 0579d8c1d10a..f6e08cbc26f0 100644 --- a/test/python/pulse/test_calibrationbuilder.py +++ b/test/python/pulse/test_calibrationbuilder.py @@ -27,7 +27,7 @@ DriveChannel, GaussianSquare, ) -from qiskit.transpiler.passes.scheduling.calibration_creators import ( +from qiskit.transpiler.passes.transformation.calibration_creators import ( RZXCalibrationBuilderNoEcho, ) from qiskit.test.mock import FakeAthens From 59bb4b6fdf85665262be429a1b4230021d220862 Mon Sep 17 00:00:00 2001 From: Vaibhaw Kumar Date: Mon, 12 Jul 2021 19:07:36 -0400 Subject: [PATCH 3/8] resolving reformat issue --- qiskit/transpiler/passes/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/transpiler/passes/__init__.py b/qiskit/transpiler/passes/__init__.py index f9fb19f63498..5f8476393709 100644 --- a/qiskit/transpiler/passes/__init__.py +++ b/qiskit/transpiler/passes/__init__.py @@ -88,7 +88,7 @@ DynamicalDecoupling AlignMeasures ValidatePulseGates - + Transformation ================= RZXCalibrationBuilder From e667ba207dbf4800dbb7d3bd67cc1e791d8fa61e Mon Sep 17 00:00:00 2001 From: Vaibhaw Kumar Date: Mon, 12 Jul 2021 22:06:31 -0400 Subject: [PATCH 4/8] duplicate import was removed --- qiskit/transpiler/passes/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/qiskit/transpiler/passes/__init__.py b/qiskit/transpiler/passes/__init__.py index 19b20401f321..df0a18f0024a 100644 --- a/qiskit/transpiler/passes/__init__.py +++ b/qiskit/transpiler/passes/__init__.py @@ -194,7 +194,6 @@ from .scheduling import TimeUnitConversion from .scheduling import ALAPSchedule from .scheduling import ASAPSchedule -from .scheduling import RZXCalibrationBuilder from .scheduling import RZXCalibrationBuilderNoEcho from .scheduling import DynamicalDecoupling from .scheduling import AlignMeasures From f5d2c5619022d16a646068145fc46f3f32ddc74f Mon Sep 17 00:00:00 2001 From: amitracal Date: Tue, 13 Jul 2021 13:22:34 -0700 Subject: [PATCH 5/8] Took care of review comments by Kevin Krsulich --- .../passes/scheduling/calibration_creators.py | 6 ++++++ .../passes/scheduling/rzx_templates.py | 4 ++++ .../transformation/calibration_creators.py | 19 ++++++++++++++----- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/qiskit/transpiler/passes/scheduling/calibration_creators.py b/qiskit/transpiler/passes/scheduling/calibration_creators.py index 4c138de25739..844a86b305a5 100644 --- a/qiskit/transpiler/passes/scheduling/calibration_creators.py +++ b/qiskit/transpiler/passes/scheduling/calibration_creators.py @@ -68,6 +68,10 @@ def run(self, dag): return dag + warnings.warn("The scheduling.calibration_creators.py has been deprecated " + "and replaced by transformation.calibration_creators.py.", + DeprecationWarning, stacklevel=2) + class RZXCalibrationBuilder(CalibrationCreator): """ @@ -384,3 +388,5 @@ def get_calibration(self, params: List, qubits: List) -> Schedule: rzx_theta = rzx_theta.insert(0, Delay(cr.duration, DriveChannel(control))) return rzx_theta + + diff --git a/qiskit/transpiler/passes/scheduling/rzx_templates.py b/qiskit/transpiler/passes/scheduling/rzx_templates.py index 54a095d066df..b61781a23d33 100644 --- a/qiskit/transpiler/passes/scheduling/rzx_templates.py +++ b/qiskit/transpiler/passes/scheduling/rzx_templates.py @@ -47,3 +47,7 @@ def rzx_templates(template_list: List[str] = None): rzx_dict = {"template_list": templates, "user_cost_dict": cost_dict} return rzx_dict + + warnings.warn("The scheduling.rzx_templates.py has been deprecated " + "and replaced by transformation.rzx_templates.py.", + DeprecationWarning, stacklevel=2) \ No newline at end of file diff --git a/qiskit/transpiler/passes/transformation/calibration_creators.py b/qiskit/transpiler/passes/transformation/calibration_creators.py index 5b44e9cffbf5..4c138de25739 100644 --- a/qiskit/transpiler/passes/transformation/calibration_creators.py +++ b/qiskit/transpiler/passes/transformation/calibration_creators.py @@ -269,11 +269,13 @@ class RZXCalibrationBuilderNoEcho(RZXCalibrationBuilder): """ Creates calibrations for RZXGate(theta) by stretching and compressing Gaussian square pulses in the CX gate. - The RZXCalibrationBuilderNoEcho is a variation of the RZXCalibrationBuilder - as it creates calibrations for the cross-resonance pulses without inserting + + The ``RZXCalibrationBuilderNoEcho`` is a variation of the + :class:`~qiskit.transpiler.passes.RZXCalibrationBuilder` pass + that creates calibrations for the cross-resonance pulses without inserting the echo pulses in the pulse schedule. This enables exposing the echo in the cross-resonance sequence as gates so that the transpiler can simplify them. - The RZXCalibrationBuilderNoEcho only supports the hardware-native direction + The ``RZXCalibrationBuilderNoEcho`` only supports the hardware-native direction of the CX gate. """ @@ -281,11 +283,13 @@ class RZXCalibrationBuilderNoEcho(RZXCalibrationBuilder): def _filter_control(inst: (int, Union["Schedule", Instruction])) -> bool: """ Looks for Gaussian square pulses applied to control channels. + Args: inst: Instructions to be filtered. + Returns: match: True if the instruction is a Play instruction with - a Gaussian square pulse on the ControlChannel. + a Gaussian square pulse on the ControlChannel. """ if isinstance(inst[1], Play): if isinstance(inst[1].pulse, GaussianSquare) and isinstance( @@ -299,11 +303,13 @@ def _filter_control(inst: (int, Union["Schedule", Instruction])) -> bool: def _filter_drive(inst: (int, Union["Schedule", Instruction])) -> bool: """ Looks for Gaussian square pulses applied to drive channels. + Args: inst: Instructions to be filtered. + Returns: match: True if the instruction is a Play instruction with - a Gaussian square pulse on the DriveChannel. + a Gaussian square pulse on the DriveChannel. """ if isinstance(inst[1], Play): if isinstance(inst[1].pulse, GaussianSquare) and isinstance( @@ -316,12 +322,15 @@ def _filter_drive(inst: (int, Union["Schedule", Instruction])) -> bool: def get_calibration(self, params: List, qubits: List) -> Schedule: """ Builds the calibration schedule for the RZXGate(theta) without echos. + Args: params: Parameters of the RZXGate(theta). I.e. params[0] is theta. qubits: List of qubits for which to get the schedules. The first qubit is the control and the second is the target. + Returns: schedule: The calibration schedule for the RZXGate(theta). + Raises: QiskitError: If the control and target qubits cannot be identified, or the backend does not support a cx gate between the qubits, or the backend does not natively From dc770e11b5dbb6f040fce11dedea2be00e0cfe35 Mon Sep 17 00:00:00 2001 From: Vaibhaw Kumar Date: Tue, 13 Jul 2021 18:06:23 -0400 Subject: [PATCH 6/8] resolved identation issues --- .../passes/scheduling/calibration_creators.py | 9 ++++----- qiskit/transpiler/passes/scheduling/rzx_templates.py | 10 ++++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/qiskit/transpiler/passes/scheduling/calibration_creators.py b/qiskit/transpiler/passes/scheduling/calibration_creators.py index 844a86b305a5..09a6467e6dda 100644 --- a/qiskit/transpiler/passes/scheduling/calibration_creators.py +++ b/qiskit/transpiler/passes/scheduling/calibration_creators.py @@ -68,11 +68,6 @@ def run(self, dag): return dag - warnings.warn("The scheduling.calibration_creators.py has been deprecated " - "and replaced by transformation.calibration_creators.py.", - DeprecationWarning, stacklevel=2) - - class RZXCalibrationBuilder(CalibrationCreator): """ Creates calibrations for RZXGate(theta) by stretching and compressing @@ -106,6 +101,10 @@ def __init__(self, backend: basebackend): self._inst_map = backend.defaults().instruction_schedule_map self._config = backend.configuration() self._channel_map = backend.configuration().qubit_channel_mapping + + warnings.warn("The scheduling.calibration_creators.py has been deprecated " + "and replaced by transformation.calibration_creators.py.", + DeprecationWarning, stacklevel=2) def supported(self, node_op: DAGNode) -> bool: """ diff --git a/qiskit/transpiler/passes/scheduling/rzx_templates.py b/qiskit/transpiler/passes/scheduling/rzx_templates.py index b61781a23d33..11394378d398 100644 --- a/qiskit/transpiler/passes/scheduling/rzx_templates.py +++ b/qiskit/transpiler/passes/scheduling/rzx_templates.py @@ -46,8 +46,10 @@ def rzx_templates(template_list: List[str] = None): rzx_dict = {"template_list": templates, "user_cost_dict": cost_dict} + warnings.warn( + "The scheduling.rzx_templates.py has been deprecated " + "and replaced by transformation.rzx_templates.py.", + DeprecationWarning, + stacklevel=2, + ) return rzx_dict - - warnings.warn("The scheduling.rzx_templates.py has been deprecated " - "and replaced by transformation.rzx_templates.py.", - DeprecationWarning, stacklevel=2) \ No newline at end of file From 6f8f55b8dbeae93c603fb9ff17924fb1b6cc3aa9 Mon Sep 17 00:00:00 2001 From: Vaibhaw Kumar Date: Tue, 13 Jul 2021 19:25:35 -0400 Subject: [PATCH 7/8] resolved tab issue --- .../passes/scheduling/calibration_creators.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/qiskit/transpiler/passes/scheduling/calibration_creators.py b/qiskit/transpiler/passes/scheduling/calibration_creators.py index 09a6467e6dda..c4738d845f8e 100644 --- a/qiskit/transpiler/passes/scheduling/calibration_creators.py +++ b/qiskit/transpiler/passes/scheduling/calibration_creators.py @@ -68,6 +68,7 @@ def run(self, dag): return dag + class RZXCalibrationBuilder(CalibrationCreator): """ Creates calibrations for RZXGate(theta) by stretching and compressing @@ -101,10 +102,13 @@ def __init__(self, backend: basebackend): self._inst_map = backend.defaults().instruction_schedule_map self._config = backend.configuration() self._channel_map = backend.configuration().qubit_channel_mapping - - warnings.warn("The scheduling.calibration_creators.py has been deprecated " - "and replaced by transformation.calibration_creators.py.", - DeprecationWarning, stacklevel=2) + + warnings.warn( + "The scheduling.calibration_creators.py has been deprecated " + "and replaced by transformation.calibration_creators.py.", + DeprecationWarning, + stacklevel=2, + ) def supported(self, node_op: DAGNode) -> bool: """ @@ -387,5 +391,3 @@ def get_calibration(self, params: List, qubits: List) -> Schedule: rzx_theta = rzx_theta.insert(0, Delay(cr.duration, DriveChannel(control))) return rzx_theta - - From d4b0690ce756870ffc9299656183c673ff0f0c6c Mon Sep 17 00:00:00 2001 From: Vaibhaw Kumar Date: Tue, 13 Jul 2021 21:24:15 -0400 Subject: [PATCH 8/8] imported warnings --- qiskit/transpiler/passes/scheduling/calibration_creators.py | 1 + qiskit/transpiler/passes/scheduling/rzx_templates.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/qiskit/transpiler/passes/scheduling/calibration_creators.py b/qiskit/transpiler/passes/scheduling/calibration_creators.py index c4738d845f8e..bc375f5aad24 100644 --- a/qiskit/transpiler/passes/scheduling/calibration_creators.py +++ b/qiskit/transpiler/passes/scheduling/calibration_creators.py @@ -12,6 +12,7 @@ """Calibration creators.""" +import warnings import math from typing import List, Union from abc import abstractmethod diff --git a/qiskit/transpiler/passes/scheduling/rzx_templates.py b/qiskit/transpiler/passes/scheduling/rzx_templates.py index 11394378d398..cf7ae1004f80 100644 --- a/qiskit/transpiler/passes/scheduling/rzx_templates.py +++ b/qiskit/transpiler/passes/scheduling/rzx_templates.py @@ -13,7 +13,7 @@ """ Convenience function to load RZXGate based templates. """ - +import warnings from typing import List from qiskit.circuit.library.templates.rzx import rzx_zz1, rzx_zz2, rzx_zz3, rzx_yz, rzx_xz, rzx_cy