From a909e699aa55a65c4655559fa9ad291a61330a22 Mon Sep 17 00:00:00 2001
From: Ali Asadi <10773383+maliasadi@users.noreply.github.com>
Date: Thu, 22 Aug 2024 11:42:17 -0400
Subject: [PATCH 1/6] Support the generalization of basis state preparation

---
 tests/lightning_qubit/test_state_vector_class.py |  4 ++--
 tests/lightning_tensor/test_tensornet_class.py   |  4 ++--
 tests/new_api/test_device.py                     | 10 +++++-----
 tests/test_apply.py                              |  8 ++------
 4 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/tests/lightning_qubit/test_state_vector_class.py b/tests/lightning_qubit/test_state_vector_class.py
index d192c8c346..42233fc64d 100644
--- a/tests/lightning_qubit/test_state_vector_class.py
+++ b/tests/lightning_qubit/test_state_vector_class.py
@@ -58,10 +58,10 @@ def test_wrong_dtype(dtype):
 
 
 def test_errors_basis_state():
-    with pytest.raises(ValueError, match="BasisState parameter must consist of 0 or 1 integers."):
+    with pytest.raises(ValueError, match="Basis state must only consist of 0s and 1s;"):
         state_vector = LightningStateVector(2)
         state_vector.apply_operations([qml.BasisState(np.array([-0.2, 4.2]), wires=[0, 1])])
-    with pytest.raises(ValueError, match="BasisState parameter and wires must be of equal length."):
+    with pytest.raises(ValueError, match="State must be of length 1;"):
         state_vector = LightningStateVector(1)
         state_vector.apply_operations([qml.BasisState(np.array([0, 1]), wires=[0])])
 
diff --git a/tests/lightning_tensor/test_tensornet_class.py b/tests/lightning_tensor/test_tensornet_class.py
index c5af8a4af2..845c1ef991 100644
--- a/tests/lightning_tensor/test_tensornet_class.py
+++ b/tests/lightning_tensor/test_tensornet_class.py
@@ -57,10 +57,10 @@ def test_wrong_device_name():
 
 def test_errors_basis_state():
     """Test that errors are raised when applying a BasisState operation."""
-    with pytest.raises(ValueError, match="BasisState parameter must consist of 0 or 1 integers."):
+    with pytest.raises(ValueError, match="Basis state must only consist of 0s and 1s;"):
         tensornet = LightningTensorNet(3, 5)
         tensornet.apply_operations([qml.BasisState(np.array([-0.2, 4.2]), wires=[0, 1])])
-    with pytest.raises(ValueError, match="BasisState parameter and wires must be of equal length."):
+    with pytest.raises(ValueError, match="State must be of length 1;"):
         tensornet = LightningTensorNet(3, 5)
         tensornet.apply_operations([qml.BasisState(np.array([0, 1]), wires=[0])])
 
diff --git a/tests/new_api/test_device.py b/tests/new_api/test_device.py
index 31f66a31be..e13893f49a 100644
--- a/tests/new_api/test_device.py
+++ b/tests/new_api/test_device.py
@@ -349,8 +349,9 @@ def test_preprocess_state_prep_first_op_decomposition(self, op, is_trainable):
         device = LightningDevice(wires=3)
 
         if is_trainable:
-            # Need to decompose twice as the state prep ops we use first decompose into a template
-            decomp = op.decomposition()[0].decomposition()
+            decomp = op.decomposition()
+            # decompose one more time if it's decomposed into a template:
+            decomp = decomp[0].decomposition() if len(decomp) == 1 else decomp
         else:
             decomp = [op]
 
@@ -367,7 +368,7 @@ def test_preprocess_state_prep_first_op_decomposition(self, op, is_trainable):
             (qml.StatePrep(np.array([1, 0]), wires=0), 1),
             (qml.BasisState([1, 1], wires=[0, 1]), 1),
             (qml.BasisState(qml.numpy.array([1, 1]), wires=[0, 1]), 1),
-            (qml.AmplitudeEmbedding([1 / np.sqrt(2), 1 / np.sqrt(2)], wires=0), 2),
+            (qml.AmplitudeEmbedding([1 / np.sqrt(2), 1 / np.sqrt(2)], wires=0), 1),
             (qml.MottonenStatePreparation([1 / np.sqrt(2), 1 / np.sqrt(2)], wires=0), 0),
         ],
     )
@@ -378,8 +379,7 @@ def test_preprocess_state_prep_middle_op_decomposition(self, op, decomp_depth):
         )
         device = LightningDevice(wires=3)
 
-        for _ in range(decomp_depth):
-            op = op.decomposition()[0]
+        op = op.decomposition()[0] if decomp_depth and len(op.decomposition()) == 1 else op
         decomp = op.decomposition()
 
         program, _ = device.preprocess()
diff --git a/tests/test_apply.py b/tests/test_apply.py
index 7cecbd550d..6f6366dc77 100644
--- a/tests/test_apply.py
+++ b/tests/test_apply.py
@@ -500,14 +500,10 @@ def test_apply_errors_qubit_state_vector(self, stateprep, qubit_device):
 
     def test_apply_errors_basis_state(self, qubit_device):
         dev = qubit_device(wires=2)
-        with pytest.raises(
-            ValueError, match="BasisState parameter must consist of 0 or 1 integers."
-        ):
+        with pytest.raises(ValueError, match="Basis state must only consist of 0s and 1s;"):
             dev.apply([qml.BasisState(np.array([-0.2, 4.2]), wires=[0, 1])])
 
-        with pytest.raises(
-            ValueError, match="BasisState parameter and wires must be of equal length."
-        ):
+        with pytest.raises(ValueError, match="State must be of length 1;"):
             dev.apply([qml.BasisState(np.array([0, 1]), wires=[0])])
 
         with pytest.raises(

From f167cad41a5440d791a2772d1e5e19b46c3536b2 Mon Sep 17 00:00:00 2001
From: ringo-but-quantum <github-ringo-but-quantum@xanadu.ai>
Date: Thu, 22 Aug 2024 15:43:30 +0000
Subject: [PATCH 2/6] Auto update version from '0.38.0-dev42' to '0.38.0-dev43'

---
 pennylane_lightning/core/_version.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pennylane_lightning/core/_version.py b/pennylane_lightning/core/_version.py
index f68075d103..33a207e9fb 100644
--- a/pennylane_lightning/core/_version.py
+++ b/pennylane_lightning/core/_version.py
@@ -16,4 +16,4 @@
    Version number (major.minor.patch[-label])
 """
 
-__version__ = "0.38.0-dev42"
+__version__ = "0.38.0-dev43"

From e466dc23103f02986bd6b2d4acdca6de09aedcb1 Mon Sep 17 00:00:00 2001
From: Ali Asadi <10773383+maliasadi@users.noreply.github.com>
Date: Thu, 22 Aug 2024 12:11:57 -0400
Subject: [PATCH 3/6] Update: Sum of amplitudes-squared does not equal one

---
 tests/test_apply.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/test_apply.py b/tests/test_apply.py
index 6f6366dc77..13b8bcd93c 100644
--- a/tests/test_apply.py
+++ b/tests/test_apply.py
@@ -488,7 +488,7 @@ def test_apply_operation_preserve_pointer_two_wires_with_parameters(
     def test_apply_errors_qubit_state_vector(self, stateprep, qubit_device):
         """Test that apply fails for incorrect state preparation, and > 2 qubit gates"""
         dev = qubit_device(wires=2)
-        with pytest.raises(ValueError, match="Sum of amplitudes-squared does not equal one."):
+        with pytest.raises(ValueError, match="The state must be a vector of norm 1.0;"):
             dev.apply([stateprep(np.array([1, -1]), wires=[0])])
 
         with pytest.raises(

From c1c9cc32b79fdf1b94d2df0f054185d19ef2ad74 Mon Sep 17 00:00:00 2001
From: Ali Asadi <10773383+maliasadi@users.noreply.github.com>
Date: Thu, 22 Aug 2024 12:28:28 -0400
Subject: [PATCH 4/6] Fix LGPU multimpi unit tests

---
 mpitests/test_adjoint_jacobian.py | 19 ++++------
 mpitests/test_apply.py            | 59 ++++++++++++++++---------------
 2 files changed, 37 insertions(+), 41 deletions(-)

diff --git a/mpitests/test_adjoint_jacobian.py b/mpitests/test_adjoint_jacobian.py
index 4b6eef51e3..a1d4be0260 100644
--- a/mpitests/test_adjoint_jacobian.py
+++ b/mpitests/test_adjoint_jacobian.py
@@ -649,14 +649,13 @@ def dev(self, request):
             batch_obs=request.param[1],
         )
 
-    def test_finite_shots_warning(self):
-        """Tests that a warning is raised when computing the adjoint diff on a device with finite shots"""
+    def test_finite_shots_error(self):
+        """Tests that an error is raised when computing the adjoint diff on a device with finite shots"""
 
         dev = qml.device(device_name, wires=8, mpi=True, shots=1)
 
-        with pytest.warns(
-            UserWarning,
-            match="Requested adjoint differentiation to be computed with finite shots.",
+        with pytest.raises(
+            qml.QuantumFunctionError, match="does not support adjoint with requested circuit."
         ):
 
             @qml.qnode(dev, diff_method="adjoint")
@@ -664,10 +663,6 @@ def circ(x):
                 qml.RX(x, wires=0)
                 return qml.expval(qml.PauliZ(0))
 
-        with pytest.warns(
-            UserWarning,
-            match="Requested adjoint differentiation to be computed with finite shots.",
-        ):
             qml.grad(circ)(0.1)
 
     def test_qnode(self, mocker, dev):
@@ -689,7 +684,7 @@ def circuit(x, y, z):
             return qml.expval(qml.PauliX(0) @ qml.PauliZ(1))
 
         qnode1 = QNode(circuit, dev, diff_method="adjoint")
-        spy = mocker.spy(dev, "adjoint_jacobian")
+        spy = mocker.spy(dev.target_device, "adjoint_jacobian")
 
         grad_fn = qml.grad(qnode1)
         grad_A = grad_fn(*args)
@@ -731,7 +726,7 @@ def cost(p1, p2):
         zero_state = np.array([1.0, 0.0])
         cost(reused_p, other_p)
 
-        spy = mocker.spy(dev, "adjoint_jacobian")
+        spy = mocker.spy(dev.target_device, "adjoint_jacobian")
 
         # analytic gradient
         grad_fn = qml.grad(cost)
@@ -770,7 +765,7 @@ def circuit(params):
             qml.Rot(params[1], params[0], 2 * params[0], wires=[0])
             return qml.expval(qml.PauliX(0))
 
-        spy_analytic = mocker.spy(dev, "adjoint_jacobian")
+        spy_analytic = mocker.spy(dev.target_device, "adjoint_jacobian")
 
         h = 1e-3 if dev.R_DTYPE == np.float32 else 1e-7
         tol = 1e-3 if dev.R_DTYPE == np.float32 else 1e-7
diff --git a/mpitests/test_apply.py b/mpitests/test_apply.py
index 8bffcc6b29..17d91cd2d7 100644
--- a/mpitests/test_apply.py
+++ b/mpitests/test_apply.py
@@ -672,29 +672,30 @@ def test_sample_dimensions(self, C_DTYPE):
         """
         num_wires = numQubits
 
-        dev = qml.device("lightning.gpu", wires=num_wires, mpi=True, shots=1000, c_dtype=C_DTYPE)
-
-        dev.apply([qml.RX(1.5708, wires=[0]), qml.RX(1.5708, wires=[1])])
-
-        dev.shots = 10
-        dev._wires_measured = {0}
-        dev._samples = dev.generate_samples()
-        s1 = dev.sample(qml.PauliZ(wires=[0]))
-        assert np.array_equal(s1.shape, (10,))
-
-        dev.reset()
-        dev.shots = 12
-        dev._wires_measured = {1}
-        dev._samples = dev.generate_samples()
-        s2 = dev.sample(qml.PauliZ(wires=[1]))
-        assert np.array_equal(s2.shape, (12,))
-
-        dev.reset()
-        dev.shots = 17
-        dev._wires_measured = {0, 1}
-        dev._samples = dev.generate_samples()
-        s3 = dev.sample(qml.PauliX(0) @ qml.PauliZ(1))
-        assert np.array_equal(s3.shape, (17,))
+        dev = qml.device("lightning.gpu", wires=num_wires, mpi=True, c_dtype=C_DTYPE)
+
+        ops = [qml.RX(1.5708, wires=[0]), qml.RX(1.5708, wires=[1])]
+
+        shots = 10
+        obs = qml.PauliZ(wires=[0])
+        tape = qml.tape.QuantumScript(ops, [qml.sample(op=obs)], shots=shots)
+        s1 = dev.execute(tape)
+
+        assert np.array_equal(s1.shape, (shots,))
+
+        shots = 12
+        obs = qml.PauliZ(wires=[1])
+        tape = qml.tape.QuantumScript(ops, [qml.sample(op=obs)], shots=shots)
+        s2 = dev.execute(tape)
+
+        assert np.array_equal(s2.shape, (shots,))
+
+        shots = 17
+        obs = qml.PauliX(0) @ qml.PauliZ(1)
+        tape = qml.tape.QuantumScript(ops, [qml.sample(op=obs)], shots=shots)
+        s3 = dev.execute(tape)
+
+        assert np.array_equal(s3.shape, (shots,))
 
     @pytest.mark.parametrize("C_DTYPE", [np.complex128, np.complex64])
     def test_sample_values(self, tol, C_DTYPE):
@@ -703,13 +704,13 @@ def test_sample_values(self, tol, C_DTYPE):
         """
         num_wires = numQubits
 
-        dev = qml.device("lightning.gpu", wires=num_wires, mpi=True, shots=1000, c_dtype=C_DTYPE)
-        dev.reset()
-        dev.apply([qml.RX(1.5708, wires=[0])])
-        dev._wires_measured = {0}
-        dev._samples = dev.generate_samples()
+        dev = qml.device("lightning.gpu", wires=num_wires, mpi=True, c_dtype=C_DTYPE)
 
-        s1 = dev.sample(qml.PauliZ(0))
+        shots = qml.measurements.Shots(1000)
+        ops = [qml.RX(1.5708, wires=[0])]
+        obs = qml.PauliZ(0)
+        tape = qml.tape.QuantumScript(ops, [qml.sample(op=obs)], shots=shots)
+        s1 = dev.execute(tape)
 
         # s1 should only contain 1 and -1, which is guaranteed if
         # they square to 1

From 62d9a0c152e29467ae8ccecd2583a50c6fb78511 Mon Sep 17 00:00:00 2001
From: Ali Asadi <10773383+maliasadi@users.noreply.github.com>
Date: Thu, 22 Aug 2024 13:04:29 -0400
Subject: [PATCH 5/6] Update changelog

---
 .github/CHANGELOG.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md
index 8700d31532..0ff382d5c8 100644
--- a/.github/CHANGELOG.md
+++ b/.github/CHANGELOG.md
@@ -33,11 +33,15 @@
 
 ### Improvements
 
+* Update Lightning tests to support the generalization of basis state preparation.
+  [(#864)](https://github.com/PennyLaneAI/pennylane-lightning/pull/864)
+
 * Multiple calls to the `append_mps_final_state()` API is allowed in `lightning.tensor`.
   [(#830)](https://github.com/PennyLaneAI/pennylane-lightning/pull/830)
   
 * Update `generate_samples` in `LightningKokkos` and `LightningGPU` to support `qml.measurements.Shots` type instances.
   [(#839)](https://github.com/PennyLaneAI/pennylane-lightning/pull/839)
+  [(#864)](https://github.com/PennyLaneAI/pennylane-lightning/pull/864)
 
 * LightningQubit gains native support for the `PauliRot` gate.
   [(#834)](https://github.com/PennyLaneAI/pennylane-lightning/pull/834)

From 8e117ff9d20b7b7e7603f143e0132ce9bc698599 Mon Sep 17 00:00:00 2001
From: Ali Asadi <10773383+maliasadi@users.noreply.github.com>
Date: Thu, 22 Aug 2024 13:35:30 -0400
Subject: [PATCH 6/6] trigger ci