Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the class RZXCalibrationBuilderNoEcho #6300

Merged
merged 15 commits into from
May 22, 2021
Merged
Show file tree
Hide file tree
Changes from 4 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
113 changes: 111 additions & 2 deletions qiskit/transpiler/passes/scheduling/calibration_creators.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@
"""Calibration creators."""

import math
from typing import List
from typing import List, Union
from abc import abstractmethod
import numpy as np

from qiskit.pulse import Play, ShiftPhase, Schedule, ControlChannel, DriveChannel, GaussianSquare
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
Expand Down Expand Up @@ -245,3 +247,110 @@ def get_calibration(self, params: List, qubits: List) -> Schedule:
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:
"""
Filters the Schedule instructions for a Gaussian square pulse on the ControlChannel.
catornow marked this conversation as resolved.
Show resolved Hide resolved
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:
"""
Filters the Schedule instructions for a Gaussian square pulse on the DriveChannel.
catornow marked this conversation as resolved.
Show resolved Hide resolved
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, the backend
does not support cx between the qubits or the backend does not natively support the
specified direction of the cx.
catornow marked this conversation as resolved.
Show resolved Hide resolved
"""
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 not isinstance(inst, ShiftPhase):
catornow marked this conversation as resolved.
Show resolved Hide resolved
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.')

# 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)))

# Reverse direction of the ZX.
if control == qubits[0]:
return rzx_theta
else:
raise QiskitError('Reverse direction not supported.')
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
features:
- |
The RZXCalibrationBuilderNoEcho creates calibrations for RZXGate(theta) 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.