Skip to content

Commit 99c5489

Browse files
authored
Merge branch 'master' into sc-91994-ub24-up
2 parents 98a15bd + c64a0c6 commit 99c5489

File tree

6 files changed

+46
-9
lines changed

6 files changed

+46
-9
lines changed

.github/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@
4343
Updating ROCM from 5.7 to 6.2.4.
4444
[(#1158)](https://github.com/PennyLaneAI/pennylane-lightning/pull/1158)
4545

46+
- Fix using Torch with `AmplitudeEmbedding` by applying `qml.broadcast_expand` before decomposition in the preprocessing stage.
47+
[(#1175)](https://github.com/PennyLaneAI/pennylane-lightning/pull/1175)
48+
4649
<h3>Internal changes ⚙️</h3>
4750

4851
- Use local catalyst repository instead of fetching on Github CI.

pennylane_lightning/lightning_gpu/lightning_gpu.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ def _add_adjoint_transforms(program: TransformProgram) -> None:
169169

170170
name = "adjoint + lightning.gpu"
171171
program.add_transform(no_sampling, name=name)
172+
program.add_transform(qml.transforms.broadcast_expand)
172173
program.add_transform(
173174
decompose,
174175
stopping_condition=_adjoint_ops,
@@ -180,7 +181,6 @@ def _add_adjoint_transforms(program: TransformProgram) -> None:
180181
program.add_transform(
181182
validate_measurements, analytic_measurements=adjoint_measurements, name=name
182183
)
183-
program.add_transform(qml.transforms.broadcast_expand)
184184
program.add_transform(validate_adjoint_trainable_params)
185185

186186

pennylane_lightning/lightning_kokkos/lightning_kokkos.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ def _add_adjoint_transforms(program: TransformProgram) -> None:
159159

160160
name = "adjoint + lightning.kokkos"
161161
program.add_transform(no_sampling, name=name)
162+
program.add_transform(qml.transforms.broadcast_expand)
162163
program.add_transform(
163164
decompose,
164165
stopping_condition=_adjoint_ops,
@@ -170,7 +171,6 @@ def _add_adjoint_transforms(program: TransformProgram) -> None:
170171
program.add_transform(
171172
validate_measurements, analytic_measurements=adjoint_measurements, name=name
172173
)
173-
program.add_transform(qml.transforms.broadcast_expand)
174174
program.add_transform(validate_adjoint_trainable_params)
175175

176176

pennylane_lightning/lightning_qubit/lightning_qubit.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ def _add_adjoint_transforms(program: TransformProgram) -> None:
163163

164164
name = "adjoint + lightning.qubit"
165165
program.add_transform(no_sampling, name=name)
166+
program.add_transform(qml.transforms.broadcast_expand)
166167
program.add_transform(
167168
decompose,
168169
stopping_condition=_adjoint_ops,
@@ -174,7 +175,6 @@ def _add_adjoint_transforms(program: TransformProgram) -> None:
174175
program.add_transform(
175176
validate_measurements, analytic_measurements=adjoint_measurements, name=name
176177
)
177-
program.add_transform(qml.transforms.broadcast_expand)
178178
program.add_transform(validate_adjoint_trainable_params)
179179

180180

tests/lightning_base/test_device.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@
102102
if not LightningDevice._CPP_BINARY_AVAILABLE: # pylint: disable=protected-access
103103
pytest.skip("No binary module found. Skipping.", allow_module_level=True)
104104

105-
fixture_params = itertools.product([3, None], [np.complex64, np.complex128]) # wires x c_dtype
105+
fixture_params = list(
106+
itertools.product([3, None], [np.complex64, np.complex128])
107+
) # wires x c_dtype
106108

107109

108110
@pytest.fixture(params=fixture_params)
@@ -191,6 +193,7 @@ def test_add_adjoint_transforms(self):
191193

192194
name = f"adjoint + {device_name}"
193195
expected_program.add_transform(no_sampling, name=name)
196+
expected_program.add_transform(qml.transforms.broadcast_expand)
194197
expected_program.add_transform(
195198
decompose,
196199
stopping_condition=_adjoint_ops,
@@ -204,7 +207,6 @@ def test_add_adjoint_transforms(self):
204207
analytic_measurements=adjoint_measurements,
205208
name=name,
206209
)
207-
expected_program.add_transform(qml.transforms.broadcast_expand)
208210
expected_program.add_transform(validate_adjoint_trainable_params)
209211

210212
actual_program = qml.transforms.core.TransformProgram()
@@ -699,6 +701,7 @@ def test_preprocess(self, adjoint):
699701
if adjoint:
700702
name = f"adjoint + {device_name}"
701703
expected_program.add_transform(no_sampling, name=name)
704+
expected_program.add_transform(qml.transforms.broadcast_expand)
702705
expected_program.add_transform(
703706
decompose,
704707
stopping_condition=_adjoint_ops,
@@ -712,7 +715,6 @@ def test_preprocess(self, adjoint):
712715
analytic_measurements=adjoint_measurements,
713716
name=name,
714717
)
715-
expected_program.add_transform(qml.transforms.broadcast_expand)
716718
expected_program.add_transform(validate_adjoint_trainable_params)
717719

718720
gradient_method = "adjoint" if adjoint else None

tests/test_adjoint_jacobian.py

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@
4646

4747
kokkos_args += [InitializationSettings().set_num_threads(2)]
4848

49-
fixture_params = itertools.product(
50-
[np.complex64, np.complex128], kokkos_args, [None, 3] # c_dtype x kokkos_args x wires
49+
fixture_params = list(
50+
itertools.product(
51+
[np.complex64, np.complex128], kokkos_args, [None, 3] # c_dtype x kokkos_args x wires
52+
)
5153
)
5254

5355

@@ -566,7 +568,12 @@ class TestAdjointJacobianQNode:
566568

567569
@pytest.fixture(params=fixture_params)
568570
def dev(self, request):
569-
return qml.device(device_name, wires=request.param[1], c_dtype=request.param[0])
571+
params = request.param
572+
if device_name == "lightning.kokkos":
573+
return qml.device(
574+
device_name, wires=params[2], c_dtype=params[0], kokkos_args=params[1]
575+
)
576+
return qml.device(device_name, wires=params[2], c_dtype=params[0])
570577

571578
def test_qnode(self, mocker, dev):
572579
"""Test that specifying diff_method allows the adjoint method to be selected"""
@@ -988,6 +995,31 @@ def f(params1, params2):
988995

989996
assert np.allclose(grad_adjoint, grad_fd, atol=tol)
990997

998+
def test_torch_amplitude_embedding(self, dev):
999+
"""Test that the adjoint Jacobian works with AmplitudeEmbedding in a TorchLayer"""
1000+
1001+
torch = pytest.importorskip("torch")
1002+
1003+
# Define a simple circuit with AmplitudeEmbedding and BasicEntanglerLayers
1004+
n_qubits = 3
1005+
qml.AmplitudeEmbedding.ndim_params = (1,)
1006+
1007+
@qml.qnode(dev)
1008+
def qnode(inputs, weights):
1009+
qml.AmplitudeEmbedding(inputs, wires=range(n_qubits), normalize=True)
1010+
qml.BasicEntanglerLayers(weights, wires=range(n_qubits))
1011+
return [qml.expval(qml.PauliZ(wires=i)) for i in range(n_qubits)]
1012+
1013+
n_layers = 1
1014+
weight_shapes = {"weights": (n_layers, n_qubits)}
1015+
1016+
qlayer = qml.qnn.TorchLayer(qnode, weight_shapes)
1017+
clayer_1 = torch.nn.Linear(2, 8)
1018+
xs_test = torch.tensor([[-0.7380, 0.3596], [-0.1870, 0.9423]])
1019+
1020+
t = clayer_1(xs_test)
1021+
qlayer(t)
1022+
9911023

9921024
def circuit_ansatz(params, wires):
9931025
"""Circuit ansatz containing all the parametrized gates"""

0 commit comments

Comments
 (0)