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

Add pulse support to the PennyLane-Braket plugin for the OQC device #15

Open
wants to merge 159 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
159 commits
Select commit Hold shift + click to select a range
7561817
Merge branch 'main' of github.com:lillian542/amazon-braket-pennylane-…
lillian542 Mar 9, 2023
3317d00
Merge branch 'aws:main' into main
lillian542 Mar 24, 2023
dc760b1
Merge branch 'main' of github.com:lillian542/amazon-braket-pennylane-…
lillian542 Apr 20, 2023
bb77ca3
Added `ParametrizedEvolution` support to OQC Lucy
mudit2812 May 8, 2023
c18cff9
Merge branch 'aws:main' into main
mudit2812 May 8, 2023
bb72e98
feat: add Python 3.11 support (#148)
AbeCoull Apr 24, 2023
b01eeab
prepare release v1.14.0
Apr 25, 2023
90df591
update development version to v1.14.1.dev0
Apr 25, 2023
6fa6487
test: parallelize test execution for pytest (#152)
AbeCoull Apr 25, 2023
9389258
prepare release v1.14.1
Apr 26, 2023
f1b2871
update development version to v1.14.2.dev0
Apr 26, 2023
1b1f4f0
feat: Add AHS devices (#158)
lillian542 May 1, 2023
fd107bc
Postprocess jacobian result shape (#159)
albi3ro May 2, 2023
01ea0ea
fix: Tempfix for failing tests (#161)
lillian542 May 2, 2023
faaa1b4
prepare release v1.15.0
May 2, 2023
4df929e
update development version to v1.15.1.dev0
May 2, 2023
91ee7a0
doc: Correct README format for PyPI (#162)
speller26 May 2, 2023
cdd977e
prepare release v1.15.0.post0
May 2, 2023
e4d9290
update development version to v1.15.1.dev0
May 2, 2023
e3fdd0e
Merge branch 'main' into oqc_pulse
mudit2812 May 8, 2023
77fab34
Merge branch 'main' of github.com:lillian542/amazon-braket-pennylane-…
lillian542 May 15, 2023
53bb218
tests work weeeeee
mudit2812 May 16, 2023
9ad62b3
Added PE to PulseSequence translation
mudit2812 May 16, 2023
29b439a
Updated to support multiple pulses
mudit2812 May 23, 2023
24a1132
Added comments for readability
mudit2812 May 23, 2023
4f7d99d
Merge branch 'main' into oqc_ps
mudit2812 May 23, 2023
e9ea0fd
Update src/braket/pennylane_plugin/translation.py
mudit2812 May 24, 2023
4154886
Refactoring
mudit2812 May 24, 2023
b4ac186
Merge branch 'main' of github.com:lillian542/amazon-braket-pennylane-…
lillian542 May 24, 2023
834a28d
add anharmonicities
lillian542 May 25, 2023
b8e8cd3
Remove coupling from settings
lillian542 May 26, 2023
44a2af9
add tests
lillian542 May 26, 2023
5b63a95
tox formatting
lillian542 May 26, 2023
6b0eb40
fix code formatting issues
lillian542 May 26, 2023
35885aa
Added test for pulse gate translation
mudit2812 May 26, 2023
5fe872e
Merge branch 'main' into oqc_ps
Qottmann May 29, 2023
0c726b2
Merge branch 'oqc_ps' into add_settings
lillian542 May 29, 2023
bb36cd1
Merge branch 'add_settings' of github.com:lillian542/amazon-braket-pe…
lillian542 May 29, 2023
c35371e
apply suggestions from code review
lillian542 May 29, 2023
c5945e7
fix failing tests
lillian542 May 29, 2023
700858c
docstrings
lillian542 May 29, 2023
80f228e
Merge branch 'main' into oqc_ps
mudit2812 Jul 5, 2023
3fd06b2
Updated translation to stop fixing amplitude
mudit2812 Jul 5, 2023
5711ce0
Reformatting
mudit2812 Jul 5, 2023
669b781
change name from settings to pulse_settings
lillian542 Jul 5, 2023
fdc4284
Apply suggestions from code review
mudit2812 Jul 5, 2023
740b2f9
Added back translation for AAMS
mudit2812 Jul 5, 2023
41406d4
Merge branch 'oqc_ps' of github.com:lillian542/amazon-braket-pennylan…
lillian542 Jul 6, 2023
10ff315
Add `ParametrizedEvolution` to OQC Lucy's supported operations (#10)
mudit2812 Jul 7, 2023
8f5f508
fix: constrain tensorflow version (#185)
shpface Jul 6, 2023
51fb522
prepare release v1.17.1
Jul 6, 2023
29c4ba0
update development version to v1.17.2.dev0
Jul 6, 2023
ee3a5db
Add `ParametrizedEvolution` to OQC Lucy's supported operations (#10)
mudit2812 Jul 7, 2023
f94e2f4
Added unit tests
mudit2812 Jul 10, 2023
19791d0
Linting
mudit2812 Jul 10, 2023
1560ceb
Merge branch 'oqc_main' into oqc_ps
mudit2812 Jul 10, 2023
9292406
Merge branch 'oqc_ps' of github.com:lillian542/amazon-braket-pennylan…
lillian542 Jul 10, 2023
605c8c5
Updated return value of wires
mudit2812 Jul 10, 2023
83bc69c
Updated variable name
mudit2812 Jul 10, 2023
dec26af
Merge branch 'oqc_ps' of github.com:lillian542/amazon-braket-pennylan…
lillian542 Jul 12, 2023
7f8d8ba
Update src/braket/pennylane_plugin/translation.py
mudit2812 Jul 12, 2023
35d7cf5
Updated tests
mudit2812 Jul 12, 2023
aa2de54
`Merge branch 'oqc_ps' of github.com:lillian542/amazon-braket-pennyla…
lillian542 Jul 12, 2023
ebb389f
pulse validation
lillian542 Jul 13, 2023
a76bd55
Merge branch 'aws:main' into oqc_main
mudit2812 Jul 13, 2023
0ad3e25
Add translation function to get `PulseGate` from `ParametrizedEvoluti…
mudit2812 Jul 14, 2023
3263b49
Merge branch 'oqc_main' into add_settings
lillian542 Jul 18, 2023
846e66c
Merge branch 'add_settings' of github.com:lillian542/amazon-braket-pe…
lillian542 Jul 18, 2023
a348594
remove unwanted changes to translation.py
lillian542 Jul 18, 2023
f7279ea
revert unwanted changes to shadow_expval tests
lillian542 Jul 18, 2023
0f7ec85
fix typo from last commit
lillian542 Jul 18, 2023
a18c02d
Merge branch 'add_settings' of github.com:lillian542/amazon-braket-pe…
lillian542 Jul 18, 2023
9fe140e
remove unwanted changes to test_translation
lillian542 Jul 18, 2023
93342ad
linting
lillian542 Jul 18, 2023
3e739d0
more lint
lillian542 Jul 18, 2023
3190959
raise clear NotImplementedError if pulse properties are called on oth…
lillian542 Jul 18, 2023
3499a1b
update tests
lillian542 Jul 18, 2023
18241de
Merge pull request #12 from lillian542/add_settings
lillian542 Jul 19, 2023
d03801a
Merge branch 'oqc_main' of github.com:lillian542/amazon-braket-pennyl…
lillian542 Jul 19, 2023
c1f7ca6
Fix formatting
lillian542 Jul 19, 2023
e97b180
Merge branch 'oqc_main' into pulse_validation
lillian542 Jul 19, 2023
e09496a
Merge branch 'pulse_validation' of github.com:lillian542/amazon-brake…
lillian542 Jul 19, 2023
587b7d5
clean up after merge conflict
lillian542 Jul 19, 2023
77b0148
warn if pulse settings don't match
lillian542 Jul 19, 2023
132e556
update validation functions
lillian542 Jul 20, 2023
007e52b
add tests that mostly work
lillian542 Jul 20, 2023
3ab782a
working freq range test
lillian542 Jul 20, 2023
4dc4e70
tox formatting
lillian542 Jul 20, 2023
36b297d
allow qml.pulse.constant as constant parameters
lillian542 Jul 20, 2023
cc361d7
Apply suggestions from code review
mudit2812 Jul 21, 2023
7866c9a
Added callable related changes to translation
mudit2812 Jul 21, 2023
fed25e4
Merge branch 'main' into oqc_main
mudit2812 Jul 21, 2023
1b7585d
Fix compatibility with the new Projector class (#189)
BorjaRequena Jul 16, 2023
b8b35ec
prepare release v1.17.4
Jul 17, 2023
681e9e7
update development version to v1.17.5.dev0
Jul 17, 2023
54b00da
infra: Update CODEOWNERS (#184)
shpface Jul 18, 2023
52d0a02
feat: native mode (#187)
ajberdy Jul 19, 2023
f8dd527
prepare release v1.18.0
Jul 20, 2023
5ad7674
update development version to v1.18.1.dev0
Jul 20, 2023
2c9b544
Merge branch 'oqc_main' into pulse_validation
mudit2812 Jul 24, 2023
dda0886
Adding docs
mudit2812 Jul 24, 2023
019ce9d
Updated docs
mudit2812 Jul 25, 2023
7f097ae
Updated white spacing
mudit2812 Jul 25, 2023
df1aec4
Updated docs
mudit2812 Jul 25, 2023
6c93999
Pulse validation (#14)
lillian542 Jul 25, 2023
64bde9c
Merge branch 'oqc_main' into oqc-docs
mudit2812 Jul 25, 2023
dfae25f
Merge pull request #16 from lillian542/oqc-docs
Qottmann Jul 26, 2023
da253ce
Merge branch 'main' into oqc_main
mudit2812 Jul 26, 2023
7256533
Merge branch 'main' into oqc_main
mudit2812 Jul 27, 2023
675edf3
Merge branch 'main' into oqc_main
mudit2812 Jul 27, 2023
fb8695a
Merge branch 'oqc_main' of github.com:lillian542/amazon-braket-pennyl…
lillian542 Aug 9, 2023
b967cd5
remove custom wire logic
lillian542 Aug 9, 2023
5a24d48
use AwsDevice instead of BraketAwsQubitDevice
lillian542 Aug 9, 2023
b312f6f
remove stray print statement
lillian542 Aug 9, 2023
d98a617
Merge pull request #17 from lillian542/wire_mapping_fix
lillian542 Aug 10, 2023
7a32aaf
Merge branch 'oqc_main' of github.com:lillian542/amazon-braket-pennyl…
lillian542 Aug 14, 2023
9313623
use ConstantWaveform for pulse.constant
lillian542 Aug 14, 2023
2fa85e9
chronological wire ordering
lillian542 Aug 14, 2023
4832c48
update docstring
lillian542 Aug 14, 2023
d3fec35
further clarify docstring
lillian542 Aug 14, 2023
159da09
Merge pull request #18 from lillian542/cont_wf
lillian542 Aug 14, 2023
76b6270
Merge pull request #19 from lillian542/frame_order
lillian542 Aug 14, 2023
40ac227
Merge branch 'oqc_main' of github.com:lillian542/amazon-braket-pennyl…
lillian542 Aug 14, 2023
3acbf71
clarify comment in validate_pulse_parameters
lillian542 Aug 14, 2023
bff2226
update _is_single_qubit_12_frame error message
lillian542 Aug 14, 2023
a7d8f58
make device required for ParametrizedEvolution dispatch
lillian542 Aug 14, 2023
277decb
update documentation
lillian542 Aug 14, 2023
10d4512
black
lillian542 Aug 14, 2023
3a24676
update check_validity
lillian542 Aug 14, 2023
0d9da08
received
lillian542 Aug 14, 2023
9417784
Merge branch 'oqc_main' of github.com:lillian542/amazon-braket-pennyl…
lillian542 Aug 14, 2023
4c772b0
update units documentation
lillian542 Aug 14, 2023
fca9ad6
fix formatting
lillian542 Aug 14, 2023
a225170
add integration test
lillian542 Aug 15, 2023
a4cc953
black formatting
lillian542 Aug 15, 2023
07c96ca
handle device offline in integ tests
lillian542 Aug 17, 2023
16013fc
remove unused import in test file
lillian542 Aug 17, 2023
7514d65
Merge branch 'main' into oqc_main
speller26 Aug 18, 2023
57f8031
Merge branch 'main' into oqc_main
speller26 Aug 21, 2023
e0228ec
:Merge branch 'oqc_main' of github.com:lillian542/amazon-braket-penny…
lillian542 Aug 22, 2023
694f0f3
set frequency range to 3-8 GHz
lillian542 Aug 22, 2023
b8a5cc5
replace self.wires with wires
lillian542 Aug 22, 2023
af725ae
update error and tests for frequency range
lillian542 Aug 25, 2023
4a68443
use frame-specific dt value
lillian542 Aug 25, 2023
f42d508
tox/formatting clean up
lillian542 Aug 25, 2023
823640b
move json dumps to seperate file pt1
lillian542 Aug 25, 2023
578e899
move json dumps to seperate file pt2
lillian542 Aug 25, 2023
378e305
Merge branch 'main' into oqc_main
christianbmadsen Sep 28, 2023
1bfa8f7
Merge branch 'oqc_main' of github.com:lillian542/amazon-braket-pennyl…
lillian542 Oct 2, 2023
33d90b2
remove warning when Ev operator contains interaction term
lillian542 Oct 2, 2023
1eeb347
flake8 and black formatting
lillian542 Oct 2, 2023
30b9396
Merge branch 'main' into oqc_main
kshitijc Oct 18, 2023
f6db25c
Update to use shift_phase
lillian542 Oct 19, 2023
152a2a2
Merge branch 'main' into oqc_main
Qottmann Oct 19, 2023
e75a081
Update src/braket/pennylane_plugin/translation.py
lillian542 Oct 19, 2023
84a1869
Update src/braket/pennylane_plugin/translation.py
lillian542 Oct 19, 2023
6ba36b8
Update src/braket/pennylane_plugin/translation.py
Qottmann Oct 20, 2023
6bac245
Merge branch 'main' into oqc_main
Qottmann Oct 24, 2023
1104612
remove unused imports
Qottmann Oct 24, 2023
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
44 changes: 43 additions & 1 deletion doc/devices/braket_remote.rst
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,52 @@ from :mod:`braket.pennylane_plugin.ops <.ops>`:
braket.pennylane_plugin.GPi2
braket.pennylane_plugin.MS

Pulse Programming
~~~~~~~~~~~~~~~~~

The PennyLane-Braket plugin provides pulse-level control for the OQC Lucy QPU through PennyLane's `ParametrizedEvolution <https://docs.pennylane.ai/en/latest/code/api/pennylane.pulse.ParametrizedEvolution.html>`_
operation. Compatible pulse Hamiltonians can be defined using the `qml.pulse.transmon_drive <https://docs.pennylane.ai/en/latest/code/api/pennylane.pulse.transmon_drive.html>`_
function and used to create ``ParametrizedEvolution``'s using `qml.evolve <https://docs.pennylane.ai/en/stable/code/api/pennylane.evolve.html>`_:

.. code-block:: python

duration = 15
def amp(p, t):
return qml.pulse.pwc(duration)(p, t)

dev = qml.device("braket.aws.qubit", wires=8, device_arn="arn:aws:braket:eu-west-2::device/qpu/oqc/Lucy")

drive = qml.pulse.transmon.transmon_drive(amplitude=amp, phase=0, freq=4.8, wires=[0])

@qml.qnode(dev)
def circuit(params, t):
qml.evolve(drive)(params, t)
return qml.expval(qml.PauliZ(wires=0))

Note that the ``freq`` argument of ``qml.pulse.transmon_drive`` is specified in GHz, and for
hardware upload the amplitude will be interpreted as an output power for control hardware in volts.
The ``phase`` must be specified in radians.

The pulse settings for the device can be obtained using the ``pulse_settings`` property. These settings can be used to describe the transmon
interaction Hamiltonian using `qml.pulse.transmon_interaction <https://docs.pennylane.ai/en/latest/code/api/pennylane.pulse.transmon_interaction.html>`_:

.. code-block:: python

dev = qml.device("braket.aws.qubit", wires=8, device_arn="arn:aws:braket:eu-west-2::device/qpu/oqc/Lucy")
pulse_settings = dev.pulse_settings
couplings = [0.01]*len(connections)
H = qml.pulse.transmon_interaction(**pulse_settings, coupling=couplings)

By passing ``pulse_settings`` from the remote device to ``qml.pulse.transmon_interaction``, an ``H`` Hamiltonian term is created using
the constants specific to the hardware. This is relevant for simulating the hardware in PennyLane on the ``default.qubit`` device.

Note that the user must supply coupling coefficients, as these are not available from the hardware backend. On the order of 10 MHz
(0.01 GHz) is in a realistic range.

Gradient computation on Braket with a QAOA Hamiltonian
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Currently, PennyLane will compute grouping indices for QAOA Hamiltonians and use them to split the Hamiltonian into multiple expectation values. If you wish to use `SV1’s adjoint differentiation capability<https://docs.aws.amazon.com/braket/latest/developerguide/hybrid.html>` when running QAOA from PennyLane, you will need reconstruct the cost Hamiltonian to remove the grouping indices from the cost Hamiltonian, like so:

Currently, PennyLane will compute grouping indices for QAOA Hamiltonians and use them to split the Hamiltonian into multiple expectation values. If you wish to use `SV1’s adjoint differentiation capability <https://docs.aws.amazon.com/braket/latest/developerguide/hybrid.html>`_ when running QAOA from PennyLane, you will need reconstruct the cost Hamiltonian to remove the grouping indices from the cost Hamiltonian, like so:

.. code-block:: python

Expand Down
2 changes: 1 addition & 1 deletion doc/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
sphinx
sphinx-automodapi
pennylane>=0.23.0
pennylane>=0.31.0
pennylane-sphinx-theme
209 changes: 208 additions & 1 deletion src/braket/pennylane_plugin/braket_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,12 +420,15 @@ def apply(
else:
param_names.append(None)
param_index += 1

dev_wires = self.map_wires(operation.wires).tolist()
gate = translate_operation(
operation,
use_unique_params=bool(trainable_indices) or use_unique_params,
param_names=param_names,
device=self._device,
)
dev_wires = self.map_wires(operation.wires).tolist()

ins = Instruction(gate, dev_wires)
circuit.add_instruction(ins)

Expand Down Expand Up @@ -708,6 +711,107 @@ def _run_snapshots(self, snapshot_circuits, n_qubits, mapped_wires):

return outcomes

def _check_pulse_frequency_validity(self, ev):
"""Confirm that, for each waveform on the ParametrizedEvolution operator, the frequency
setting is a constant, and the value is within the frequency range for the relevant frame;
if not, raise an error"""

# confirm all frequency values are constant (or the qml.pulse.constant function)
callable_freqs = [
pulse.frequency
for pulse in ev.H.pulses
if (callable(pulse.frequency) and pulse.frequency != qml.pulse.constant)
]

if callable_freqs:
raise RuntimeError(
"Expected all frequencies to be constants or qml.pulse.constant, "
"but received callable(s)"
)

# confirm all frequencies are within permitted difference from center frequency
param_idx = 0
for pulse in ev.H.pulses:
freq = pulse.frequency
# track the index for parameters in case we need to evaluate qml.pulse.constant
if callable(pulse.amplitude):
param_idx += 1
if callable(pulse.phase):
param_idx += 1
if callable(pulse.frequency):
# if frequency is callable, its qml.pulse.constant and equal to its parameter
freq = ev.parameters[param_idx]
param_idx += 1

wires = self.map_wires(pulse.wires).tolist()
freq_min = 3 # GHz
freq_max = 8

if not (freq_min < freq < freq_max):
raise RuntimeError(
f"Frequency range for wire(s) {wires} is between {freq_min} "
f"and {freq_max} GHz, but received {freq} GHz."
)

def _validate_pulse_parameters(self, ev):
"""Validates pulse input (ParametrizedEvolution) before converting to a PulseGate"""

# note: the pulse upload on the AWS service checks at task creation that the max amplitude
# is not exceeded, so that check has not been included here

# confirm frequencies are constant and within the permitted frequency range for the channel
self._check_pulse_frequency_validity(ev)

# confirm all phase values are constant (or the qml.pulse.constant function)
callable_phase = [
pulse.phase
for pulse in ev.H.pulses
if (callable(pulse.phase) and pulse.phase != qml.pulse.constant)
]

if callable_phase:
raise RuntimeError(
"Expected all phases to be constants or qml.pulse.constant, "
"but received callable(s)"
)

# ensure each ParametrizedEvolution/PulseGate contains at most one waveform per frame/wire
wires_used = []
for pulse in ev.H.pulses:
for wire in pulse.wires:
if wire in wires_used:
raise RuntimeError(
f"Multiple waveforms assigned to wire {wire} in the same "
f"ParametrizedEvolution gate"
)
wires_used.append(wire)

def check_validity(self, queue, observables):
"""Check validity of pulse operations before running the standard check_validity function

Checks whether the operations and observables in queue are all supported by the device. Runs
the standard check_validity function for a PennyLane device, and an additional check to
validate any pulse-operations in the form of a ParametrizedEvolution operation.

Args:
queue (Iterable[~.operation.Operation]): quantum operation objects which are intended
to be applied on the device
observables (Iterable[~.operation.Observable]): observables which are intended
to be evaluated on the device

Raises:
DeviceError: if there are operations in the queue or observables that the device does
not support
RuntimeError: if there are ParametrizedEvolution operations in the queue that are not
supported because of invalid pulse parameters
"""

super().check_validity(queue, observables)

for op in queue:
if isinstance(op, qml.pulse.ParametrizedEvolution):
self._validate_pulse_parameters(op)

def capabilities(self=None):
"""Add support for AG on sv1"""
# normally, we'd just call super().capabilities() here, but super()
Expand Down Expand Up @@ -754,6 +858,109 @@ def execute_and_gradients(self, circuits, **kwargs):
jacs.append(new_jac)
return res, jacs

def _is_single_qubit_01_frame(self, f_string, wire=None):
"""Defines the condition for selecting frames addressing the qubit (01)
drive based on frame name"""
if self._device.arn == "arn:aws:braket:eu-west-2::device/qpu/oqc/Lucy":
if wire is not None:
return f_string == f"q{wire}_drive"
return "drive" in f_string
else:
raise NotImplementedError(
f"Single-qubit drive frame for pulse control not defined for "
f"device {self._device.arn}"
)

def _is_single_qubit_12_frame(self, f_string, wire=None):
"""Defines the condition for selecting frames addressing excitation to
the second excited state based on frame name"""
if self._device.arn == "arn:aws:braket:eu-west-2::device/qpu/oqc/Lucy":
if wire is not None:
return f_string == f"q{wire}_second_state"
return "second_state" in f_string
else:
raise NotImplementedError(
f"Second excitation drive frame for pulse control not defined for "
f"device {self._device.arn}"
)

def _get_frames(self, filter, wires):
"""Takes a filter defining how the relevant frames are labelled, and returns all the frames
that fit, i.e.:

cond = lambda frame_id, wire: f"q{wire}_drive" == frame_id
frames = self._get_frames(cond, wires=[0, 1, 2])

would return all the frames with ids "q0_drive" "q1_drive", and "q2_drive", stored
in a dictionary with keys [0, 1, 2] identifying the qubit number.
"""
if not self._device.arn == "arn:aws:braket:eu-west-2::device/qpu/oqc/Lucy":
raise NotImplementedError(
f"Accessing drive frame for pulse control is not defined for "
f"device {self._device.arn}"
)

frames = {}
for wire in wires:
for frame, info in self._device.properties.pulse.dict()["frames"].items():
if filter(frame, wire):
frames[wire] = info

return frames

@property
def pulse_settings(self):
"""Dictionary of constants set by the hardware (qubit resonant frequencies,
inter-qubit connection graph, wires and anharmonicities).

Used to enable initializing hardware-consistent Hamiltonians by returning
values that would need to be passed, i.e.:

>>> dev_remote = qml.device('braket.aws.qubit',
>>> wires=8,
>>> arn='arn:aws:braket:eu-west-2::device/qpu/oqc/Lucy')
>>> pulse_settings = dev_remote.pulse_settings
>>> H_int = qml.pulse.transmon_interaction(**pulse_settings, coupling=0.02)

By passing the ``pulse_settings`` from the remote device to ``transmon_interaction``, an
``H_int`` Hamiltonian term is created using the constants specific to the hardware.
This is relevant for simulating the hardware in PennyLane on the ``default.qubit`` device.

Note that the user must supply coupling coefficients, as these are not available from the
hardware backend.
"""
if not self._device.arn == "arn:aws:braket:eu-west-2::device/qpu/oqc/Lucy":
raise NotImplementedError(
f"The pulse_settings property for pulse control is not defined for "
f"device {self._device.arn}"
)

device_info = self._device.properties.paradigm
wires = [i for i in range(device_info.qubitCount)]

drive_frames_01 = self._get_frames(filter=self._is_single_qubit_01_frame, wires=wires)
drive_frames_12 = self._get_frames(filter=self._is_single_qubit_12_frame, wires=wires)

qubit_freq = [drive_frames_01[wire]["frequency"] * 1e-9 for wire in wires] # Hz to GHz

connections = []
for q1, connected_qubits in device_info.connectivity.connectivityGraph.items():
for q2 in connected_qubits:
connection = (int(q1), int(q2))
connections.append(connection)

anharmonicity = [
(drive_frames_01[wire]["frequency"] - drive_frames_12[wire]["frequency"]) * 1e-9
for wire in wires
]

return {
"qubit_freq": qubit_freq,
"connections": connections,
"wires": wires,
"anharmonicity": anharmonicity,
}


class BraketLocalQubitDevice(BraketQubitDevice):
r"""Amazon Braket LocalSimulator qubit device for PennyLane.
Expand Down
Loading