Skip to content

Commit

Permalink
Deprecate legacy devices (#620)
Browse files Browse the repository at this point in the history
* Deprecating IroiseMVP

* Replacing Chadoq2 with DigitalAnalogDevice

* Changes to docs and tutorials (part 1)

* Formating

* Tutorial modifications (part 2)

* Fix bugs in tutorials
  • Loading branch information
HGSilveri authored Dec 1, 2023
1 parent b18e434 commit a0c59a6
Show file tree
Hide file tree
Showing 31 changed files with 5,168 additions and 5,093 deletions.
5 changes: 3 additions & 2 deletions docs/source/apidoc/core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,11 @@ Physical Devices
Each `Device`` instance holds the characteristics of a physical device,
which when associated with a :class:`pulser.Sequence` condition its development.

.. autodata:: pulser.devices.Chadoq2

.. autodata:: pulser.devices.AnalogDevice

.. autodata:: pulser.devices.DigitalAnalogDevice



Channels
---------------------
Expand Down
6 changes: 3 additions & 3 deletions docs/source/intro_rydberg_blockade.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"outputs": [],
"source": [
"from pulser import Register\n",
"from pulser.devices import Chadoq2\n",
"from pulser.devices import DigitalAnalogDevice\n",
"\n",
"layers = 3\n",
"reg = Register.hexagon(layers)\n",
Expand Down Expand Up @@ -105,7 +105,7 @@
"\n",
"pi_pulse = Pulse.ConstantDetuning(BlackmanWaveform(duration, np.pi), 0.0, 0.0)\n",
"\n",
"seq = Sequence(reg, Chadoq2)\n",
"seq = Sequence(reg, DigitalAnalogDevice)\n",
"\n",
"seq.declare_channel(\"ryd\", \"rydberg_local\", \"atom0\")\n",
"\n",
Expand Down Expand Up @@ -169,7 +169,7 @@
" reg = Register.rectangle(1, 2, spacing=R, prefix=\"atom\")\n",
"\n",
" # Pulse Sequence\n",
" seq = Sequence(reg, Chadoq2)\n",
" seq = Sequence(reg, DigitalAnalogDevice)\n",
" seq.declare_channel(\"ryd\", \"rydberg_local\", \"atom0\")\n",
" seq.add(pi_pulse, \"ryd\")\n",
" seq.target(\"atom1\", \"ryd\")\n",
Expand Down
8 changes: 7 additions & 1 deletion pulser-core/pulser/devices/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@
from typing import TYPE_CHECKING

from pulser.devices._device_datacls import Device, VirtualDevice
from pulser.devices._devices import AnalogDevice, Chadoq2, IroiseMVP
from pulser.devices._devices import (
AnalogDevice,
Chadoq2,
DigitalAnalogDevice,
IroiseMVP,
)
from pulser.devices._mock_device import MockDevice

# Registers which devices can be used to avoid definition of custom devices
Expand All @@ -27,4 +32,5 @@
Chadoq2,
IroiseMVP,
AnalogDevice,
DigitalAnalogDevice,
)
63 changes: 35 additions & 28 deletions pulser-core/pulser/devices/_devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Definitions of real devices."""
"""Examples of realistic devices."""
import dataclasses
import warnings

import numpy as np
Expand All @@ -23,8 +24,8 @@

with warnings.catch_warnings():
warnings.simplefilter("ignore", category=DeprecationWarning)
Chadoq2 = Device(
name="Chadoq2",
DigitalAnalogDevice = Device(
name="DigitalAnalogDevice",
dimensions=2,
rydberg_level=70,
max_atom_num=100,
Expand Down Expand Up @@ -71,57 +72,63 @@
),
)

IroiseMVP = Device(
name="IroiseMVP",
AnalogDevice = Device(
name="AnalogDevice",
dimensions=2,
rydberg_level=60,
max_atom_num=100,
max_radial_distance=60,
max_atom_num=25,
max_radial_distance=35,
min_atom_distance=5,
max_sequence_duration=4000,
# TODO: Define max_runs
channel_objects=(
Rydberg.Global(
max_abs_detuning=2 * np.pi * 4,
max_amp=2 * np.pi * 3,
max_abs_detuning=2 * np.pi * 20,
max_amp=2 * np.pi * 2,
clock_period=4,
min_duration=16,
max_duration=2**26,
mod_bandwidth=4,
mod_bandwidth=8,
eom_config=RydbergEOM(
limiting_beam=RydbergBeam.RED,
max_limiting_amp=40 * 2 * np.pi,
intermediate_detuning=700 * 2 * np.pi,
mod_bandwidth=24,
max_limiting_amp=30 * 2 * np.pi,
intermediate_detuning=450 * 2 * np.pi,
mod_bandwidth=40,
controlled_beams=(RydbergBeam.BLUE,),
custom_buffer_time=240,
),
),
),
pre_calibrated_layouts=(TriangularLatticeLayout(61, 5),),
)

AnalogDevice = Device(
name="AnalogDevice",
# Legacy devices (deprecated, should not be used in new sequences)

with warnings.catch_warnings():
warnings.simplefilter("ignore", category=DeprecationWarning)
Chadoq2 = dataclasses.replace(DigitalAnalogDevice, name="Chadoq2")

IroiseMVP = Device(
name="IroiseMVP",
dimensions=2,
rydberg_level=60,
max_atom_num=25,
max_radial_distance=35,
max_atom_num=100,
max_radial_distance=60,
min_atom_distance=5,
max_sequence_duration=4000,
# TODO: Define max_runs
channel_objects=(
Rydberg.Global(
max_abs_detuning=2 * np.pi * 20,
max_amp=2 * np.pi * 2,
max_abs_detuning=2 * np.pi * 4,
max_amp=2 * np.pi * 3,
clock_period=4,
min_duration=16,
mod_bandwidth=8,
max_duration=2**26,
mod_bandwidth=4,
eom_config=RydbergEOM(
limiting_beam=RydbergBeam.RED,
max_limiting_amp=30 * 2 * np.pi,
intermediate_detuning=450 * 2 * np.pi,
mod_bandwidth=40,
max_limiting_amp=40 * 2 * np.pi,
intermediate_detuning=700 * 2 * np.pi,
mod_bandwidth=24,
controlled_beams=(RydbergBeam.BLUE,),
custom_buffer_time=240,
),
),
),
pre_calibrated_layouts=(TriangularLatticeLayout(61, 5),),
)
20 changes: 20 additions & 0 deletions pulser-core/pulser/sequence/sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
from numpy.typing import ArrayLike

import pulser
import pulser.devices as devices
import pulser.sequence._decorators as seq_decorators
from pulser.channels.base_channel import Channel
from pulser.channels.dmm import DMM, _dmm_id_from_name, _get_dmm_name
Expand Down Expand Up @@ -121,6 +122,25 @@ def __init__(
f"'device' must be of type 'BaseDevice', not {type(device)}."
)

with warnings.catch_warnings():
warnings.simplefilter("always")
if device == devices.Chadoq2:
warnings.warn(
"The 'Chadoq2' device has been deprecated. For a "
"similar device combining global and local addressing, "
"consider using `DigitalAnalogDevice`.",
category=DeprecationWarning,
stacklevel=2,
)

if device == devices.IroiseMVP:
warnings.warn(
"The 'IroiseMVP' device has been deprecated. For a "
"similar analog device consider using `AnalogDevice`.",
category=DeprecationWarning,
stacklevel=2,
)

# Checks if register is compatible with the device
if isinstance(register, MappableRegister):
device.validate_layout(register.layout)
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ line-length = 79
[tool.isort]
profile = "black"
line_length = 79
skip = "__venv__"
src_paths = ["pulser-core", "pulser-simulation", "pulser-pasqal"]

[tool.pytest.ini_options]
Expand Down
50 changes: 35 additions & 15 deletions tests/test_abstract_repr.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,14 @@
from pulser import Pulse, Register, Register3D, Sequence, devices
from pulser.channels import Rydberg
from pulser.channels.eom import RydbergBeam, RydbergEOM
from pulser.devices import AnalogDevice, Chadoq2, Device, IroiseMVP, MockDevice
from pulser.devices import (
AnalogDevice,
Chadoq2,
Device,
DigitalAnalogDevice,
IroiseMVP,
MockDevice,
)
from pulser.json.abstract_repr.deserializer import (
VARIABLE_TYPE_MAP,
deserialize_device,
Expand Down Expand Up @@ -62,7 +69,7 @@
}

phys_Chadoq2 = replace(
Chadoq2,
DigitalAnalogDevice,
name="phys_Chadoq2",
dmm_objects=(
replace(Chadoq2.dmm_objects[0], total_bottom_detuning=-2000),
Expand All @@ -72,7 +79,7 @@

class TestDevice:
@pytest.fixture(
params=[Chadoq2, phys_Chadoq2, IroiseMVP, MockDevice, AnalogDevice]
params=[DigitalAnalogDevice, phys_Chadoq2, MockDevice, AnalogDevice]
)
def abstract_device(self, request):
device = request.param
Expand All @@ -96,7 +103,7 @@ def _roundtrip(abstract_device):
device = deserialize_device(json.dumps(abstract_device))
assert json.loads(device.to_abstract_repr()) == abstract_device

if abstract_device["name"] == "Chadoq2":
if abstract_device["name"] == "DigitalAnalogDevice":
with pytest.warns(
DeprecationWarning, match="From v0.17 and onwards"
):
Expand All @@ -116,7 +123,7 @@ def check_error_raised(
assert re.search(re.escape(err_msg), str(cause)) is not None
return cause

if abstract_device["name"] == "Chadoq2":
if abstract_device["name"] == "DigitalAnalogDevice":
with pytest.warns(
DeprecationWarning, match="From v0.17 and onwards"
):
Expand Down Expand Up @@ -279,7 +286,7 @@ class TestSerialization:
def triangular_lattice(self):
return TriangularLatticeLayout(50, 6)

@pytest.fixture(params=[Chadoq2, MockDevice])
@pytest.fixture(params=[DigitalAnalogDevice, MockDevice])
def sequence(self, request):
qubits = {"control": (-2, 0), "target": (2, 0)}
reg = Register(qubits)
Expand Down Expand Up @@ -312,7 +319,7 @@ def sequence(self, request):
CompositeWaveform(pi_2_wf, pi_2_wf), 0, 0
)

max_val = Chadoq2.rabi_from_blockade(8)
max_val = DigitalAnalogDevice.rabi_from_blockade(8)
two_pi_wf = BlackmanWaveform.from_max_val(max_val, amps[1])
two_pi_pulse = Pulse.ConstantDetuning(two_pi_wf, 0, 0)

Expand Down Expand Up @@ -526,7 +533,7 @@ def test_exceptions(self, sequence):
],
)
def test_unknown_calls(self, call):
seq = Sequence(Register.square(2, prefix="q"), Chadoq2)
seq = Sequence(Register.square(2, prefix="q"), DigitalAnalogDevice)
seq.declare_channel("ch0", "rydberg_global")
seq._calls.append(call)
with pytest.raises(
Expand Down Expand Up @@ -741,7 +748,7 @@ def test_mappable_register(self, triangular_lattice):
@pytest.mark.parametrize("correct_phase_drift", (False, True))
def test_eom_mode(self, triangular_lattice, correct_phase_drift):
reg = triangular_lattice.hexagonal_register(7)
seq = Sequence(reg, IroiseMVP)
seq = Sequence(reg, AnalogDevice)
seq.declare_channel("ryd", "rydberg_global")
det_off = seq.declare_variable("det_off", dtype=float)
duration = seq.declare_variable("duration", dtype=int)
Expand Down Expand Up @@ -814,7 +821,9 @@ def test_default_basis(
phase_kwargs = {} if use_default else dict(basis="ground-rydberg")
measure_kwargs = {} if use_default else dict(basis="digital")

seq = Sequence(triangular_lattice.hexagonal_register(5), Chadoq2)
seq = Sequence(
triangular_lattice.hexagonal_register(5), DigitalAnalogDevice
)
seq.declare_channel("ryd", "rydberg_global")
seq.declare_channel("raman", "raman_local", initial_target="q0")
seq.phase_shift(1, "q0", **phase_kwargs)
Expand Down Expand Up @@ -993,7 +1002,7 @@ def _get_serialized_seq(
seq_dict = {
"version": "1",
"name": "John Doe",
"device": json.loads(Chadoq2.to_abstract_repr()),
"device": json.loads(DigitalAnalogDevice.to_abstract_repr()),
"register": [
{"name": "q0", "x": 0.0, "y": 2.0},
{"name": "q42", "x": -2.0, "y": 9.0},
Expand Down Expand Up @@ -1755,7 +1764,7 @@ def test_deserialize_eom_ops(self, correct_phase_drift, var_detuning_on):
"duration": {"type": "int", "value": [100]},
"detuning_on": {"type": "int", "value": [0.0]},
},
device=json.loads(IroiseMVP.to_abstract_repr()),
device=json.loads(AnalogDevice.to_abstract_repr()),
channels={"global": "rydberg_global"},
)
if correct_phase_drift is None:
Expand Down Expand Up @@ -2158,12 +2167,23 @@ def test_unknow_waveform(self):
with patch("jsonschema.validate"):
Sequence.from_abstract_repr(json.dumps(s))

@pytest.mark.parametrize("device", [Chadoq2, IroiseMVP, MockDevice])
def test_legacy_device(self, device):
@pytest.mark.parametrize(
"device, deprecated",
[(Chadoq2, True), (IroiseMVP, True), (MockDevice, False)],
)
def test_legacy_device(self, device, deprecated):
s = _get_serialized_seq(
device=device.name, channels={"global": "rydberg_global"}
)
seq = Sequence.from_abstract_repr(json.dumps(s))
if deprecated:
# This is necessary because warnings.catch_warnings (being
# used in Sequence) overrides pytest.mark.filterwarnings
with pytest.warns(
DeprecationWarning, match="device has been deprecated"
):
seq = Sequence.from_abstract_repr(json.dumps(s))
else:
seq = Sequence.from_abstract_repr(json.dumps(s))
assert seq.device == device

def test_bad_type(self):
Expand Down
4 changes: 2 additions & 2 deletions tests/test_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
RemoteResultsError,
SubmissionStatus,
)
from pulser.devices import Chadoq2, MockDevice
from pulser.devices import DigitalAnalogDevice, MockDevice
from pulser.result import Result, SampledResult


Expand Down Expand Up @@ -246,7 +246,7 @@ def test_qpu_backend(sequence):
):
QPUBackend(sequence, connection)
with pytest.warns(DeprecationWarning, match="From v0.17"):
seq = sequence.switch_device(replace(Chadoq2, max_runs=10))
seq = sequence.switch_device(replace(DigitalAnalogDevice, max_runs=10))
qpu_backend = QPUBackend(seq, connection)
with pytest.raises(ValueError, match="'job_params' must be specified"):
qpu_backend.run()
Expand Down
Loading

0 comments on commit a0c59a6

Please sign in to comment.