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

Timeslot error fix and tests #4335

Merged
merged 11 commits into from
Apr 30, 2020
6 changes: 3 additions & 3 deletions qiskit/pulse/schedule.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def ch_duration(self, *channels: List[Channel]) -> int:
Args:
*channels: Channels within ``self`` to include.
"""
return self.ch_stop_time(channels)
return self.ch_stop_time(*channels)

def ch_start_time(self, *channels: List[Channel]) -> int:
"""Return the time of the start of the first instruction over the supplied channels.
Expand Down Expand Up @@ -669,10 +669,10 @@ def _insertion_index(intervals: List[Interval], new_interval: Interval, index: i
if len(intervals) == 1:
if _overlaps(intervals[0], new_interval):
raise PulseError("New interval overlaps with existing.")
return index if new_interval[0] < intervals[0][0] else index + 1
return index if new_interval[1] <= intervals[0][0] else index + 1

mid_idx = len(intervals) // 2
if new_interval[0] < intervals[mid_idx][0]:
if new_interval[1] <= intervals[mid_idx][0]:
return _insertion_index(intervals[:mid_idx], new_interval, index=index)
else:
return _insertion_index(intervals[mid_idx:], new_interval, index=index + mid_idx)
Expand Down
99 changes: 99 additions & 0 deletions test/python/pulse/test_schedule.py
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,90 @@ def test_shift_unshift(self):
shifted_sched = reference_sched.shift(10).shift(-10)
self.assertEqual(shifted_sched, reference_sched)

def test_duration(self):
"""Test schedule.duration."""
reference_sched = Schedule()
reference_sched = reference_sched.insert(
10, Delay(10, DriveChannel(0)))
reference_sched = reference_sched.insert(
10, Delay(50, DriveChannel(1)))
reference_sched = reference_sched.insert(
10, ShiftPhase(0.1, DriveChannel(0)))

reference_sched = reference_sched.insert(
100, ShiftPhase(0.1, DriveChannel(1)))

self.assertEqual(reference_sched.duration, 100)
self.assertEqual(reference_sched.duration, 100)

def test_ch_duration(self):
"""Test schedule.ch_duration."""
reference_sched = Schedule()
reference_sched = reference_sched.insert(
10, Delay(10, DriveChannel(0)))
reference_sched = reference_sched.insert(
10, Delay(50, DriveChannel(1)))
reference_sched = reference_sched.insert(
10, ShiftPhase(0.1, DriveChannel(0)))

reference_sched = reference_sched.insert(
100, ShiftPhase(0.1, DriveChannel(1)))

self.assertEqual(reference_sched.ch_duration(DriveChannel(0)), 20)
self.assertEqual(reference_sched.ch_duration(DriveChannel(1)), 100)
self.assertEqual(reference_sched.ch_duration(*reference_sched.channels),
reference_sched.duration)

def test_ch_start_time(self):
"""Test schedule.ch_start_time."""
reference_sched = Schedule()
reference_sched = reference_sched.insert(
10, Delay(10, DriveChannel(0)))
reference_sched = reference_sched.insert(
10, Delay(50, DriveChannel(1)))
reference_sched = reference_sched.insert(
10, ShiftPhase(0.1, DriveChannel(0)))

reference_sched = reference_sched.insert(
100, ShiftPhase(0.1, DriveChannel(1)))

self.assertEqual(reference_sched.ch_start_time(DriveChannel(0)), 10)
self.assertEqual(reference_sched.ch_start_time(DriveChannel(1)), 10)

def test_ch_stop_time(self):
"""Test schedule.ch_stop_time."""
reference_sched = Schedule()
reference_sched = reference_sched.insert(
10, Delay(10, DriveChannel(0)))
reference_sched = reference_sched.insert(
10, Delay(50, DriveChannel(1)))
reference_sched = reference_sched.insert(
10, ShiftPhase(0.1, DriveChannel(0)))

reference_sched = reference_sched.insert(
100, ShiftPhase(0.1, DriveChannel(1)))

self.assertEqual(reference_sched.ch_stop_time(DriveChannel(0)), 20)
self.assertEqual(reference_sched.ch_stop_time(DriveChannel(1)), 100)

def test_timeslots(self):
"""Test schedule.timeslots."""
reference_sched = Schedule()
reference_sched = reference_sched.insert(
10, Delay(10, DriveChannel(0)))
reference_sched = reference_sched.insert(
10, Delay(50, DriveChannel(1)))
reference_sched = reference_sched.insert(
10, ShiftPhase(0.1, DriveChannel(0)))

reference_sched = reference_sched.insert(
100, ShiftPhase(0.1, DriveChannel(1)))

self.assertEqual(
reference_sched.timeslots[DriveChannel(0)], [(10, 10), (10, 20)])
self.assertEqual(
reference_sched.timeslots[DriveChannel(1)], [(10, 60), (100, 100)])


class TestDelay(BaseTestSchedule):
"""Test Delay Instruction"""
Expand Down Expand Up @@ -866,6 +950,17 @@ def test_insertion_index(self):
self.assertEqual(_insertion_index(intervals, (5, 6)), 2)
self.assertEqual(_insertion_index(intervals, (8, 9)), 3)

longer_intervals = [(1, 2), (2, 3), (4, 5), (5, 6), (7, 9), (11, 11)]
self.assertEqual(_insertion_index(longer_intervals, (4, 4)), 2)
self.assertEqual(_insertion_index(longer_intervals, (5, 5)), 3)
self.assertEqual(_insertion_index(longer_intervals, (3, 4)), 2)
self.assertEqual(_insertion_index(longer_intervals, (3, 4)), 2)

# test when two identical zero duration timeslots are present
intervals = [(0, 10), (73, 73), (73, 73), (90, 101)]
self.assertEqual(_insertion_index(intervals, (42, 73)), 1)
self.assertEqual(_insertion_index(intervals, (73, 81)), 3)

def test_insertion_index_when_overlapping(self):
"""Test that `_insertion_index` raises an error when the new_interval _overlaps."""
intervals = [(10, 20), (44, 55), (60, 61), (80, 1000)]
Expand All @@ -874,6 +969,10 @@ def test_insertion_index_when_overlapping(self):
with self.assertRaises(PulseError):
_insertion_index(intervals, (100, 1500))

intervals = [(0, 1), (10, 15)]
with self.assertRaises(PulseError):
_insertion_index(intervals, (7, 13))

def test_insertion_index_empty_list(self):
"""Test that the insertion index is properly found for empty lists."""
self.assertEqual(_insertion_index([], (0, 1)), 0)
Expand Down