Skip to content

Commit fea5caa

Browse files
authored
Merge branch 'develop' into hs/legacy-install
2 parents 2ffc961 + b597826 commit fea5caa

File tree

3 files changed

+33
-4
lines changed

3 files changed

+33
-4
lines changed

VERSION.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.2dev0
1+
1.2dev1

pulser-core/pulser/register/register.py

+18-2
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,8 @@ def with_automatic_layout(
344344
Raises:
345345
RuntimeError: If the automatic layout generation fails to meet
346346
the device constraints.
347+
NotImplementedError: When the register has differentiable
348+
coordinates (ie torch Tensors with requires_grad=True).
347349
348350
Returns:
349351
Register: A new register instance with identical qubit IDs and
@@ -353,6 +355,15 @@ def with_automatic_layout(
353355
raise TypeError(
354356
f"'device' must be of type Device, not {type(device)}."
355357
)
358+
if (
359+
self._coords_arr.is_tensor
360+
and self._coords_arr.as_tensor().requires_grad
361+
):
362+
raise NotImplementedError(
363+
"'Register.with_automatic_layout()' does not support "
364+
"registers with differentiable coordinates."
365+
)
366+
356367
trap_coords = generate_trap_coordinates(
357368
self.sorted_coords,
358369
min_trap_dist=device.min_atom_distance,
@@ -363,8 +374,13 @@ def with_automatic_layout(
363374
max_traps=device.max_layout_traps,
364375
)
365376
layout = pulser.register.RegisterLayout(trap_coords, slug=layout_slug)
366-
trap_ids = layout.get_traps_from_coordinates(*self.sorted_coords)
367-
return cast(Register, layout.define_register(*trap_ids))
377+
trap_ids = layout.get_traps_from_coordinates(
378+
*self._coords_arr.as_array()
379+
)
380+
return cast(
381+
Register,
382+
layout.define_register(*trap_ids, qubit_ids=self.qubit_ids),
383+
)
368384

369385
def rotated(self, degrees: float) -> Register:
370386
"""Makes a new rotated register.

tests/test_register.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ def test_register_recipes_torch(
593593

594594
@pytest.mark.parametrize("optimal_filling", [None, 0.4, 0.1])
595595
def test_automatic_layout(optimal_filling):
596-
reg = Register.square(4, spacing=5)
596+
reg = Register.square(4, spacing=5, prefix="test")
597597
max_layout_filling = 0.5
598598
min_traps = int(np.ceil(len(reg.qubits) / max_layout_filling))
599599
optimal_traps = int(
@@ -610,6 +610,8 @@ def test_automatic_layout(optimal_filling):
610610

611611
# On its own, it works
612612
new_reg = reg.with_automatic_layout(device, layout_slug="foo")
613+
assert new_reg.qubit_ids == reg.qubit_ids # Same IDs in the same order
614+
assert new_reg == reg # The register itself is identical
613615
assert isinstance(new_reg.layout, RegisterLayout)
614616
assert str(new_reg.layout) == "foo"
615617
trap_num = new_reg.layout.number_of_traps
@@ -657,3 +659,14 @@ def test_automatic_layout(optimal_filling):
657659
big_reg.with_automatic_layout(device).layout.number_of_traps
658660
>= min_traps
659661
)
662+
663+
664+
def test_automatic_layout_diff():
665+
torch = pytest.importorskip("torch")
666+
with pytest.raises(
667+
NotImplementedError,
668+
match="does not support registers with differentiable coordinates",
669+
):
670+
Register.square(
671+
2, spacing=torch.tensor(10.0, requires_grad=True)
672+
).with_automatic_layout(AnalogDevice)

0 commit comments

Comments
 (0)