Skip to content

Commit

Permalink
Add tests for scheduling passes
Browse files Browse the repository at this point in the history
  • Loading branch information
mtreinish committed Jan 18, 2023
1 parent b1e2024 commit 5fed919
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def __init__(self, durations: InstructionDurations = None, target: Target = None
self.durations = target.durations()

# Ensure op node durations are attached and in consistent unit
self.requires.append(TimeUnitConversion(durations))
self.requires.append(TimeUnitConversion(inst_durations=durations, target=target))

# Initialize timeslot
if "node_start_time" in self.property_set:
Expand Down
89 changes: 85 additions & 4 deletions test/python/transpiler/test_dynamical_decoupling.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
from numpy import pi
from ddt import ddt, data

from qiskit.circuit import QuantumCircuit, Delay
from qiskit.circuit.library import XGate, YGate, RXGate, UGate
from qiskit.circuit import QuantumCircuit, Delay, Measure, Reset, Parameter
from qiskit.circuit.library import XGate, YGate, RXGate, UGate, CXGate, HGate
from qiskit.quantum_info import Operator
from qiskit.transpiler.instruction_durations import InstructionDurations
from qiskit.transpiler.passes import (
Expand All @@ -28,8 +28,8 @@
)
from qiskit.transpiler.passmanager import PassManager
from qiskit.transpiler.exceptions import TranspilerError

import qiskit.pulse as pulse
from qiskit.transpiler.target import Target, InstructionProperties
from qiskit import pulse

from qiskit.test import QiskitTestCase

Expand Down Expand Up @@ -143,6 +143,87 @@ def test_insert_dd_ghz(self):

self.assertEqual(ghz4_dd, expected)

def test_insert_dd_ghz_with_target(self):
"""Test DD gates are inserted in correct spots.
┌───┐ ┌────────────────┐ ┌───┐ »
q_0: ──────┤ H ├─────────■──┤ Delay(100[dt]) ├──────┤ X ├──────»
┌─────┴───┴─────┐ ┌─┴─┐└────────────────┘┌─────┴───┴─────┐»
q_1: ┤ Delay(50[dt]) ├─┤ X ├────────■─────────┤ Delay(50[dt]) ├»
├───────────────┴┐└───┘ ┌─┴─┐ └───────────────┘»
q_2: ┤ Delay(750[dt]) ├───────────┤ X ├───────────────■────────»
├────────────────┤ └───┘ ┌─┴─┐ »
q_3: ┤ Delay(950[dt]) ├─────────────────────────────┤ X ├──────»
└────────────────┘ └───┘ »
« ┌────────────────┐ ┌───┐ ┌────────────────┐
«q_0: ┤ Delay(200[dt]) ├──────┤ X ├───────┤ Delay(100[dt]) ├─────────────────
« └─────┬───┬──────┘┌─────┴───┴──────┐└─────┬───┬──────┘┌───────────────┐
«q_1: ──────┤ X ├───────┤ Delay(100[dt]) ├──────┤ X ├───────┤ Delay(50[dt]) ├
« └───┘ └────────────────┘ └───┘ └───────────────┘
«q_2: ───────────────────────────────────────────────────────────────────────
«
«q_3: ───────────────────────────────────────────────────────────────────────
«
"""
target = Target(num_qubits=4, dt=1)
target.add_instruction(HGate(), {(0,): InstructionProperties(duration=50)})
target.add_instruction(
CXGate(),
{
(0, 1): InstructionProperties(duration=700),
(1, 2): InstructionProperties(duration=200),
(2, 3): InstructionProperties(duration=300),
},
)
target.add_instruction(
XGate(), {(x,): InstructionProperties(duration=50) for x in range(4)}
)
target.add_instruction(
YGate(), {(x,): InstructionProperties(duration=50) for x in range(4)}
)
target.add_instruction(
UGate(Parameter("theta"), Parameter("phi"), Parameter("lambda")),
{(x,): InstructionProperties(duration=100) for x in range(4)},
)
target.add_instruction(
RXGate(Parameter("theta")),
{(x,): InstructionProperties(duration=100) for x in range(4)},
)
target.add_instruction(
Measure(), {(x,): InstructionProperties(duration=1000) for x in range(4)}
)
target.add_instruction(
Reset(), {(x,): InstructionProperties(duration=1500) for x in range(4)}
)
dd_sequence = [XGate(), XGate()]
pm = PassManager(
[
ALAPScheduleAnalysis(target=target),
PadDynamicalDecoupling(target=target, dd_sequence=dd_sequence),
]
)

ghz4_dd = pm.run(self.ghz4)

expected = self.ghz4.copy()
expected = expected.compose(Delay(50), [1], front=True)
expected = expected.compose(Delay(750), [2], front=True)
expected = expected.compose(Delay(950), [3], front=True)

expected = expected.compose(Delay(100), [0])
expected = expected.compose(XGate(), [0])
expected = expected.compose(Delay(200), [0])
expected = expected.compose(XGate(), [0])
expected = expected.compose(Delay(100), [0])

expected = expected.compose(Delay(50), [1])
expected = expected.compose(XGate(), [1])
expected = expected.compose(Delay(100), [1])
expected = expected.compose(XGate(), [1])
expected = expected.compose(Delay(50), [1])

self.assertEqual(ghz4_dd, expected)

def test_insert_dd_ghz_one_qubit(self):
"""Test DD gates are inserted on only one qubit.
Expand Down
34 changes: 34 additions & 0 deletions test/python/transpiler/test_scheduling_padding_pass.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@

"""Test the Scheduling/PadDelay passes"""

import math
import unittest

from ddt import ddt, data, unpack
from qiskit import QuantumCircuit
from qiskit.circuit import Measure
from qiskit.circuit.library import CXGate, HGate
from qiskit.pulse import Schedule, Play, Constant, DriveChannel
from qiskit.test import QiskitTestCase
from qiskit.transpiler.instruction_durations import InstructionDurations
Expand All @@ -27,6 +30,8 @@
)
from qiskit.transpiler.passmanager import PassManager
from qiskit.transpiler.exceptions import TranspilerError
from qiskit.transpiler.target import Target, InstructionProperties
from qiskit.providers.fake_provider.fake_backend_v2 import FakeBackendV2


@ddt
Expand Down Expand Up @@ -55,6 +60,35 @@ def test_alap_agree_with_reverse_asap_reverse(self):

self.assertEqual(alap_qc, new_qc)

def test_alap_agree_with_reverse_asap_with_target(self):
"""Test if ALAP schedule agrees with doubly-reversed ASAP schedule."""
qc = QuantumCircuit(2)
qc.h(0)
qc.delay(500, 1)
qc.cx(0, 1)
qc.measure_all()

target = Target(num_qubits=2, dt=3.5555555555555554)
target.add_instruction(HGate(), {(0,): InstructionProperties(duration=200)})
target.add_instruction(CXGate(), {(0, 1): InstructionProperties(duration=700)})
target.add_instruction(
Measure(),
{
(0,): InstructionProperties(duration=1000),
(1,): InstructionProperties(duration=1000),
},
)

pm = PassManager([ALAPScheduleAnalysis(target=target), PadDelay()])
alap_qc = pm.run(qc)

pm = PassManager([ASAPScheduleAnalysis(target=target), PadDelay()])
new_qc = pm.run(qc.reverse_ops())
new_qc = new_qc.reverse_ops()
new_qc.name = new_qc.name

self.assertEqual(alap_qc, new_qc)

@data(ALAPScheduleAnalysis, ASAPScheduleAnalysis)
def test_classically_controlled_gate_after_measure(self, schedule_pass):
"""Test if ALAP/ASAP schedules circuits with c_if after measure with a common clbit.
Expand Down

0 comments on commit 5fed919

Please sign in to comment.