Skip to content

Commit

Permalink
Merge branch 'main' into pulse_qubit
Browse files Browse the repository at this point in the history
  • Loading branch information
math411 committed Jun 20, 2023
2 parents 142062d + a6093b4 commit 4432d3c
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 82 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## v1.42.2 (2023-06-20)

### Bug Fixes and Other Changes

* pulse plotting with barriers that have no argument

## v1.42.1 (2023-06-07)

### Bug Fixes and Other Changes
Expand Down
2 changes: 1 addition & 1 deletion src/braket/_sdk/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@
Version number (major.minor.patch[-label])
"""

__version__ = "1.42.2.dev0"
__version__ = "1.42.3.dev0"
3 changes: 3 additions & 0 deletions src/braket/pulse/ast/approximation_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ def visit_QuantumBarrier(self, node: ast.QuantumBarrier, context: _ParseState) -
context (_ParseState): The parse state context.
"""
frames = self._get_frame_parameters(node.qubits, context)
if len(frames) == 0:
# barrier without arguments is applied to all the frames of the context
frames = list(context.frame_data.keys())
dts = [context.frame_data[frame_id].dt for frame_id in frames]
max_time = max([context.frame_data[frame_id].current_time for frame_id in frames])
# All frames are delayed till the first multiple of the LCM([port.dts])
Expand Down
159 changes: 79 additions & 80 deletions test/unit_tests/braket/pulse/ast/test_approximation_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ def test_delay(port):
pulse_seq = PulseSequence().delay(frames=frame, duration=3e-9)
# 3 datapoints for delay


expected_amplitudes = {"frame1": TimeSeries()}
expected_frequencies = {"frame1": TimeSeries()}
expected_phases = {"frame1": TimeSeries()}

# 2 datapoints for first delay
expected_amplitudes["frame1"].put(0, 0).put(2e-9, 0)
expected_frequencies["frame1"].put(0, 1e8).put(2e-9, 1e8)
expected_phases["frame1"].put(0, 0).put(2e-9, 0)
Expand All @@ -66,7 +66,6 @@ def test_predefined_frame(port):
expected_frequencies = {"frame1": TimeSeries()}
expected_phases = {"frame1": TimeSeries()}

# 2 datapoints for first delay
expected_amplitudes["frame1"].put(0, 0).put(2e-9, 0)
expected_frequencies["frame1"].put(0, 1e8).put(2e-9, 1e8)
expected_phases["frame1"].put(0, 0).put(2e-9, 0)
Expand All @@ -93,15 +92,10 @@ def test_set_shift_phase(port):
expected_frequencies = {"frame1": TimeSeries()}
expected_phases = {"frame1": TimeSeries()}

# 2 datapoints for first delay
# Parser does not like delay 2ns
expected_amplitudes["frame1"].put(0, 0).put(1e-9, 0)
expected_frequencies["frame1"].put(0, 1e8).put(1e-9, 1e8)
expected_phases["frame1"].put(0, 1).put(1e-9, 1)

# set_shift_phase should be instantaneous (result on current or next datapoint?)
# 5 dt for second delay
# shift_phase adds 2 to the phase of the last point -> 3
expected_amplitudes["frame1"].put(2e-9, 0).put(6e-9, 0)
expected_frequencies["frame1"].put(2e-9, 1e8).put(6e-9, 1e8)
expected_phases["frame1"].put(2e-9, 3).put(6e-9, 3)
Expand All @@ -125,13 +119,11 @@ def test_set_shift_phase_beyond_2_pi(port):
expected_frequencies = {"frame1": TimeSeries()}
expected_phases = {"frame1": TimeSeries()}

# 2 datapoints for first delay
# 5pi/2 is reduced to pi/2
expected_amplitudes["frame1"].put(0, 0).put(1e-9, 0)
expected_frequencies["frame1"].put(0, 1e8).put(1e-9, 1e8)
expected_phases["frame1"].put(0, np.pi / 2).put(1e-9, np.pi / 2)

# set_shift_phase should be instantaneous (result on current or next datapoint?)
# shift_phase adds -pi to the phase of the last point -> 3pi/2
expected_amplitudes["frame1"].put(2e-9, 0).put(6e-9, 0)
expected_frequencies["frame1"].put(2e-9, 1e8).put(6e-9, 1e8)
Expand All @@ -151,22 +143,15 @@ def test_set_shift_frequency(port):
.shift_frequency(frame, -0.1e8)
.delay(frames=frame, duration=10e-9)
)
# 2 datapoints for delay
# set_shift_phase should be instantaneous (result on current or next datapoint?)
# shift_phase adds 2 to the phase of the last point -> 3

expected_amplitudes = {"frame1": TimeSeries()}
expected_frequencies = {"frame1": TimeSeries()}
expected_phases = {"frame1": TimeSeries()}

# 2 datapoints for first delay
expected_amplitudes["frame1"].put(0, 0).put(19e-9, 0)
expected_frequencies["frame1"].put(0, 2e8).put(19e-9, 2e8)
expected_phases["frame1"].put(0, 0).put(19e-9, 0)

# set_shift_phase should be instantaneous (result on current or next datapoint?)
# 5 dt for second delay
# shift_phase adds 2 to the phase of the last point -> 3
expected_amplitudes["frame1"].put(20e-9, 0).put(29e-9, 0)
expected_frequencies["frame1"].put(20e-9, 1.9e8).put(29e-9, 1.9e8)
expected_phases["frame1"].put(20e-9, 0).put(29e-9, 0)
Expand All @@ -180,7 +165,6 @@ def test_play_arbitrary_waveforms(port):
frame = Frame(frame_id="frame1", port=port, frequency=1e8, phase=0, is_predefined=False)
my_arb_wf = ArbitraryWaveform([0.4 + 0.1j, -0.8 + 0.1j, 1 + 0.2j])
pulse_seq = PulseSequence().play(frame, my_arb_wf).capture_v0(frame)
# 3 datapoints for arb wf play

expected_amplitudes = {"frame1": TimeSeries()}
expected_frequencies = {"frame1": TimeSeries()}
Expand All @@ -201,7 +185,6 @@ def test_play_literal(port):
frame = Frame(frame_id="frame1", port=port, frequency=1e8, phase=0, is_predefined=False)
pulse_seq = PulseSequence()
pulse_seq._program.play(frame=frame, waveform=[0.4 + 0.1j, -0.8 + 0.1j, 1 + 0.2j])
# 3 datapoints for arb wf play

expected_amplitudes = {"frame1": TimeSeries()}
expected_frequencies = {"frame1": TimeSeries()}
Expand Down Expand Up @@ -290,7 +273,6 @@ def test_play_gaussian_waveforms(port):
length=1e-8, sigma=1.69e-9, amplitude=1.0, zero_at_edges=False
)
pulse_seq = PulseSequence().play(frame1, gaussian_wf_ZaE_False)
# X datapoints...

times = np.arange(0, 1e-8, port.dt)
values = np.array(
Expand Down Expand Up @@ -329,21 +311,20 @@ def test_play_gaussian_waveforms(port):
length=1e-8, sigma=1.69e-9, amplitude=1.0, zero_at_edges=True
)
pulse_seq.play(frame1, gaussian_wf_ZaE_True)
# X datapoints...

times = np.arange(0, 1e-8, port.dt)
values = np.array(
[
0.0 + 0.0j,
complex(0.04879311),
complex(0.1967938),
complex(0.49004931),
complex(0.83735931),
complex(0.0),
complex(0.04879310874736347),
complex(0.1967938049565093),
complex(0.49004931075238933),
complex(0.8373593063365198),
complex(1.0),
complex(0.83735931),
complex(0.49004931),
complex(0.1967938),
complex(0.04879311),
complex(0.8373593063365196),
complex(0.49004931075238906),
complex(0.1967938049565092),
complex(0.048793108747363416),
],
dtype=np.complex128,
)
Expand Down Expand Up @@ -412,16 +393,16 @@ def test_play_drag_gaussian_waveforms(port):
times = np.arange(0, 1e-8, port.dt)
values = np.array(
[
0.0 + 0.0j,
0.04879311 + 0.06833529j,
0.1967938 + 0.20670894j,
0.49004931 + 0.34315977j,
0.83735931 + 0.29318277j,
1.0 + 0.0j,
0.83735931 - 0.29318277j,
0.49004931 - 0.34315977j,
0.1967938 - 0.20670894j,
0.04879311 - 0.06833529j,
complex(0.0, 0.0),
complex(0.04879310874736347, 0.0683352946288484),
complex(0.1967938049565093, 0.20670894396888342),
complex(0.49004931075238933, 0.34315977084303023),
complex(0.8373593063365198, 0.2931827689284408),
complex(1.0, 0),
complex(0.8373593063365196, -0.293182768928441),
complex(0.49004931075238906, -0.34315977084303023),
complex(0.1967938049565092, -0.20670894396888334),
complex(0.048793108747363416, -0.06833529462884834),
],
dtype=np.complex128,
)
Expand Down Expand Up @@ -490,29 +471,67 @@ def test_barrier_same_dt(port):
expected_frequencies["frame2"].put(shift_time_frame2 + t, 1e8)
expected_phases["frame2"].put(shift_time_frame2 + t, 0)

# # Pad frame2
# shift_time_frame2 = shift_time_frame2 + pulse_length
# last_time_frame1 = expected_amplitudes["frame1"].times()[-1]
parser = _ApproximationParser(program=pulse_seq._program, frames=to_dict([frame1, frame2]))

# # Do we need to pad frame1?
# expected_amplitudes["frame1"].put(last_time_frame1 + port.dt, 0)
# expected_frequencies["frame1"].put(last_time_frame1 + port.dt, 1e8)
# expected_phases["frame1"].put(last_time_frame1 + port.dt, 0)
verify_results(parser, expected_amplitudes, expected_frequencies, expected_phases)

# expected_amplitudes["frame2"].put(shift_time_frame2, 0).put(
# last_time_frame1 + port.dt, 0
# )
# expected_frequencies["frame2"].put(shift_time_frame2, 1e8).put(
# last_time_frame1 + port.dt, 1e8
# )
# expected_phases["frame2"].put(shift_time_frame2, 0).put(last_time_frame1 + port.dt, 0)

def test_barrier_no_args(port):
frame1 = Frame(frame_id="frame1", port=port, frequency=1e8, phase=0, is_predefined=False)
frame2 = Frame(frame_id="frame2", port=port, frequency=1e8, phase=0, is_predefined=False)
pulse_seq = (
PulseSequence()
.play(frame1, ConstantWaveform(12e-9, 0.75)) # Inst1
.barrier([]) # Inst2
.play(frame1, ConstantWaveform(16e-9, 1)) # Inst3
.play(frame2, ConstantWaveform(8e-9, -1)) # Inst4
)

expected_amplitudes = {"frame1": TimeSeries(), "frame2": TimeSeries()}
expected_frequencies = {"frame1": TimeSeries(), "frame2": TimeSeries()}
expected_phases = {"frame1": TimeSeries(), "frame2": TimeSeries()}

# Inst1
shift_time_frame1 = 0
pulse_length = 12e-9
times = np.arange(0, pulse_length, port.dt)
values = 0.75 * np.ones_like(times)
for t, v in zip(times, values):
expected_amplitudes["frame1"].put(shift_time_frame1 + t, v)
expected_frequencies["frame1"].put(shift_time_frame1 + t, 1e8)
expected_phases["frame1"].put(shift_time_frame1 + t, 0)

# Inst2
# Delay frame2 from 0ns to 11ns
shift_time_frame2 = 0

expected_amplitudes["frame2"].put(0, 0).put(11e-9, 0)
expected_frequencies["frame2"].put(0, 1e8).put(11e-9, 1e8)
expected_phases["frame2"].put(0, 0).put(11e-9, 0)

# Inst3
shift_time_frame1 = shift_time_frame1 + pulse_length
pulse_length = 16e-9
times = np.arange(0, pulse_length, port.dt)
values = 1 * np.ones_like(times)
for t, v in zip(times, values):
expected_amplitudes["frame1"].put(shift_time_frame1 + t, v)
expected_frequencies["frame1"].put(shift_time_frame1 + t, 1e8)
expected_phases["frame1"].put(shift_time_frame1 + t, 0)

# Inst4
shift_time_frame2 = shift_time_frame1
pulse_length = 8e-9
times = np.arange(0, pulse_length, port.dt)
values = -1 * np.ones_like(times)
for t, v in zip(times, values):
expected_amplitudes["frame2"].put(shift_time_frame2 + t, v)
expected_frequencies["frame2"].put(shift_time_frame2 + t, 1e8)
expected_phases["frame2"].put(shift_time_frame2 + t, 0)

parser = _ApproximationParser(program=pulse_seq._program, frames=to_dict([frame1, frame2]))

verify_results(parser, expected_amplitudes, expected_frequencies, expected_phases)
# Array retrievable with
# x=np.arange(0, ts.times()+1e-9, 1e-9)
# np.interp(x, ts.times(), ts.values()) # See last cells of SDK Testing.ipynb


def test_barrier_different_dt(port):
Expand Down Expand Up @@ -543,8 +562,7 @@ def test_barrier_different_dt(port):
expected_phases["frame1"].put(shift_time_frame1 + t, 0)

# Inst2
# barrier at 35ns (first point coinciding with frame2: np.ceil(max(20,0)/np.lcm(dt1=5,dt2=7))*np.lcm(dt1=5,dt2=7)) # noqa
# reset shift_time_frame1 = shift_time_frame2 = 35
# barrier at 40ns (first point coinciding with frame2 (every 20ns))
shift_time_frame1 = shift_time_frame2 = 40e-9

latest_time_frame1 = expected_amplitudes["frame1"].times()[-1]
Expand Down Expand Up @@ -580,13 +598,6 @@ def test_barrier_different_dt(port):
expected_frequencies["frame2"].put(shift_time_frame2 + t, 1e8)
expected_phases["frame2"].put(shift_time_frame2 + t, 0)

# # Pad frame2
# shift_time_frame2 = shift_time_frame2 + pulse_length
# last_time = 80e-9
# expected_amplitudes["frame2"].put(shift_time_frame2, 0).put(last_time, 0)
# expected_frequencies["frame2"].put(shift_time_frame2, 1e8).put(last_time, 1e8)
# expected_phases["frame2"].put(shift_time_frame2, 0).put(last_time, 0)

parser = _ApproximationParser(program=pulse_seq._program, frames=to_dict([frame1, frame2]))

verify_results(parser, expected_amplitudes, expected_frequencies, expected_phases)
Expand Down Expand Up @@ -628,18 +639,6 @@ def test_pad_different_dt(port):
expected_frequencies["frame2"].put(shift_time_frame2 + t, 1e8)
expected_phases["frame2"].put(shift_time_frame2 + t, 0)

# # Pad all frames to end up
# last_time_frame1 = expected_amplitudes["frame1"].times()[-1]
# last_time_frame2 = expected_amplitudes["frame2"].times()[-1]

# last_time = 40e-9
# expected_amplitudes["frame1"].put(last_time_frame1 + port1.dt, 0).put(last_time, 0)
# expected_frequencies["frame1"].put(last_time_frame1 + port1.dt, 1e8).put(last_time, 1e8) # noqa
# expected_phases["frame1"].put(last_time_frame1 + port1.dt, 0).put(last_time, 0)
# expected_amplitudes["frame2"].put(last_time_frame2 + port2.dt, 0).put(last_time, 0)
# expected_frequencies["frame2"].put(last_time_frame2 + port2.dt, 1e8).put(last_time, 1e8) # noqa
# expected_phases["frame2"].put(last_time_frame2 + port2.dt, 0).put(last_time, 0)

parser = _ApproximationParser(program=pulse_seq._program, frames=to_dict([frame1, frame2]))

verify_results(parser, expected_amplitudes, expected_frequencies, expected_phases)
Expand Down Expand Up @@ -709,9 +708,9 @@ def test_duration_literal():

def verify_results(results, expected_amplitudes, expected_frequencies, expected_phases):
for frame_id in expected_amplitudes.keys():
assert _all_close(results.amplitudes[frame_id], expected_amplitudes[frame_id])
assert _all_close(results.frequencies[frame_id], expected_frequencies[frame_id])
assert _all_close(results.phases[frame_id], expected_phases[frame_id])
assert _all_close(results.amplitudes[frame_id], expected_amplitudes[frame_id], 1e-10)
assert _all_close(results.frequencies[frame_id], expected_frequencies[frame_id], 1e-10)
assert _all_close(results.phases[frame_id], expected_phases[frame_id], 1e-10)


def to_dict(frames: Union[Frame, List]):
Expand Down
7 changes: 6 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
[tox]
envlist = linters,docs,unit-tests
envlist = clean,linters,docs,unit-tests

[testenv:clean]
deps = coverage
skip_install = true
commands = coverage erase

[testenv:unit-tests]
basepython = python3
Expand Down

0 comments on commit 4432d3c

Please sign in to comment.