Repository: PennyLaneAI/pennylane
Pull request #1268 (2021-05-03 08:03:58)

V0.15.1 bugfix
This bugfix PR cherry-picks all v0.15.1 bugfix PRs into the v0.15.0 branch:


- Change DeprecationWarning and PendingDeprecationWarning to UserWarning
  #1211 by mariaschuld was merged 3 days ago • Approved

- Fixes two bugs in the parameter-shift Hessian
  #1260 by josh146 was merged 3 days ago • Approved

- Fix inversion of templates
  #1243 by josh146 was merged 4 days ago • Approved

- Fix the order of arguments to the GaussianState operation
  #1255 by antalszava was merged 6 days ago • Approved

- Allow pyscf>=1.7.2 for QChem
  #1254 by antalszava was merged 7 days ago • Approved 

The only non-reviewed changes in this PR is this commit: 400fe432b4dcb378a54acaf902bddde79eeb6741

codecov[bot]: # [Codecov](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1268?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) Report
> Merging [#1268](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1268?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) (400fe43) into [v0.15.1](https://codecov.io/gh/PennyLaneAI/pennylane/commit/6252d3e1a8c570746f03af4c78d920dd5e4d11ad?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) (6252d3e) will **decrease** coverage by `0.02%`.
> The diff coverage is `92.30%`.

[![Impacted file tree graph](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1268/graphs/tree.svg?width=650&height=150&src=pr&token=9S3YzlUgGk&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI)](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1268?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI)

```diff
@@             Coverage Diff             @@
##           v0.15.1    #1268      +/-   ##
===========================================
- Coverage    98.13%   98.10%   -0.03%     
===========================================
  Files          145      145              
  Lines        10984    11005      +21     
===========================================
+ Hits         10779    10797      +18     
- Misses         205      208       +3     
```


| [Impacted Files](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1268?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) | Coverage Δ | |
|---|---|---|
| [pennylane/\_qubit\_device.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1268/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL19xdWJpdF9kZXZpY2UucHk=) | `98.50% <ø> (ø)` | |
| [pennylane/devices/default\_qubit\_jax.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1268/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL2RldmljZXMvZGVmYXVsdF9xdWJpdF9qYXgucHk=) | `94.36% <ø> (ø)` | |
| [pennylane/ops/cv.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1268/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL29wcy9jdi5weQ==) | `100.00% <ø> (ø)` | |
| [pennylane/qnode.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1268/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3Fub2RlLnB5) | `98.67% <ø> (ø)` | |
| [pennylane/vqe/vqe.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1268/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3ZxZS92cWUucHk=) | `92.81% <ø> (ø)` | |
| [pennylane/tape/tape.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1268/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3RhcGUvdGFwZS5weQ==) | `97.72% <81.25%> (-0.80%)` | :arrow_down: |
| [pennylane/\_version.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1268/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL192ZXJzaW9uLnB5) | `100.00% <100.00%> (ø)` | |
| [pennylane/beta/devices/default\_tensor.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1268/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL2JldGEvZGV2aWNlcy9kZWZhdWx0X3RlbnNvci5weQ==) | `95.22% <100.00%> (ø)` | |
| [pennylane/devices/default\_gaussian.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1268/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL2RldmljZXMvZGVmYXVsdF9nYXVzc2lhbi5weQ==) | `99.29% <100.00%> (ø)` | |
| [pennylane/devices/default\_mixed.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1268/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL2RldmljZXMvZGVmYXVsdF9taXhlZC5weQ==) | `100.00% <100.00%> (ø)` | |
| ... and [8 more](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1268/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1268?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1268?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI). Last update [6252d3e...400fe43](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1268?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI).


Patch:
diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md
index 0ad6f2d62..085683523 100644
--- a/.github/CHANGELOG.md
+++ b/.github/CHANGELOG.md
@@ -1,3 +1,38 @@
+# Release 0.15.1 (current release)
+
+<h3>Bug fixes</h3>
+
+* Fixes two bugs in the parameter-shift Hessian.
+  [(#1260)](https://github.com/PennyLaneAI/pennylane/pull/1260)
+
+  - Fixes a bug where having an unused parameter in the Autograd interface
+    would result in an indexing error during backpropagation.
+
+  - The parameter-shift Hessian only supports the two-term parameter-shift
+    rule currently, so raises an error if asked to differentiate
+    any unsupported gates (such as the controlled rotation gates).
+
+* A bug which resulted in `qml.adjoint()` and `qml.inv()` failing to work with
+  templates has been fixed.
+  [(#1243)](https://github.com/PennyLaneAI/pennylane/pull/1243)
+
+* Deprecation warning instances in PennyLane have been changed to `UserWarning`,
+  to account for recent changes to how Python warnings are filtered in
+  [PEP565](https://www.python.org/dev/peps/pep-0565/).
+  [(#1211)](https://github.com/PennyLaneAI/pennylane/pull/1211)
+
+<h3>Documentation</h3>
+
+* Updated the order of the parameters to the `GaussianState` operation to match
+  the way that the PennyLane-SF plugin uses them.
+  [(#1255)](https://github.com/PennyLaneAI/pennylane/pull/1255)
+
+<h3>Contributors</h3>
+
+This release contains contributions from (in alphabetical order):
+
+Josh Izaac, Maria Schuld, Antal Száva.
+
 # Release 0.15.0 (current release)
 
 <h3>New features since last release</h3>
@@ -622,7 +657,7 @@ fully differentiable.
   of shots is set explicitly. 
 
 * If creating a QNode from a quantum function with an argument named `shots`,
-  a `DeprecationWarning` is raised, warning the user that this is a reserved
+  a `UserWarning` is raised, warning the user that this is a reserved
   argument to change the number of shots on a per-call basis.
   [(#1075)](https://github.com/PennyLaneAI/pennylane/pull/1075)
 
diff --git a/pennylane/_qubit_device.py b/pennylane/_qubit_device.py
index 93d38a07e..1d093252e 100644
--- a/pennylane/_qubit_device.py
+++ b/pennylane/_qubit_device.py
@@ -475,7 +475,7 @@ class QubitDevice(Device):
                 "The number of shots has to be explicitly set on the device "
                 "when using sample-based measurements. Since no shots are specified, "
                 "a default of 1000 shots is used.",
-                DeprecationWarning,
+                UserWarning,
             )
 
         shots = self.shots or 1000
diff --git a/pennylane/_version.py b/pennylane/_version.py
index c27e81f03..445f0fd63 100644
--- a/pennylane/_version.py
+++ b/pennylane/_version.py
@@ -16,4 +16,4 @@
 Version number (major.minor.patch[-label])
 """
 
-__version__ = "0.15.0"
+__version__ = "0.15.1"
diff --git a/pennylane/beta/devices/default_tensor.py b/pennylane/beta/devices/default_tensor.py
index c9e23f4b2..5ea976af5 100644
--- a/pennylane/beta/devices/default_tensor.py
+++ b/pennylane/beta/devices/default_tensor.py
@@ -100,7 +100,7 @@ class DefaultTensor(Device):
     name = "PennyLane TensorNetwork simulator plugin"
     short_name = "default.tensor"
     pennylane_requires = "0.15"
-    version = "0.15.0"
+    version = "0.15.1"
     author = "Xanadu Inc."
 
     _operation_map = {
diff --git a/pennylane/devices/default_gaussian.py b/pennylane/devices/default_gaussian.py
index 729ecd14c..fb8bfdc7e 100644
--- a/pennylane/devices/default_gaussian.py
+++ b/pennylane/devices/default_gaussian.py
@@ -432,7 +432,7 @@ def thermal_state(nbar, hbar=2.0):
     return state
 
 
-def gaussian_state(mu, cov, hbar=2.0):
+def gaussian_state(cov, mu, hbar=2.0):
     r"""Returns a Gaussian state.
 
     This is simply a bare wrapper function,
@@ -444,17 +444,19 @@ def gaussian_state(mu, cov, hbar=2.0):
     ordering.
 
     Args:
-        mu (array): vector means. Must be length-:math:`2N`,
-            where N is the number of modes
         cov (array): covariance matrix. Must be dimension :math:`2N\times 2N`,
             where N is the number of modes
+        mu (array): vector means. Must be length-:math:`2N`,
+            where N is the number of modes
         hbar (float): (default 2) the value of :math:`\hbar` in the commutation
             relation :math:`[\x,\p]=i\hbar`
 
     Returns:
-        tuple: the mean and covariance matrix of the Gaussian state
+        tuple: the mean and the covariance matrix of the Gaussian state
     """
     # pylint: disable=unused-argument
+
+    # Note: the internal order of mu and cov is different to the one used in Strawberry Fields
     return mu, cov
 
 
@@ -648,7 +650,7 @@ class DefaultGaussian(Device):
     name = "Default Gaussian PennyLane plugin"
     short_name = "default.gaussian"
     pennylane_requires = "0.15"
-    version = "0.15.0"
+    version = "0.15.1"
     author = "Xanadu Inc."
 
     _operation_map = {
diff --git a/pennylane/devices/default_mixed.py b/pennylane/devices/default_mixed.py
index 2807af16f..62e4036c9 100644
--- a/pennylane/devices/default_mixed.py
+++ b/pennylane/devices/default_mixed.py
@@ -51,7 +51,7 @@ class DefaultMixed(QubitDevice):
     name = "Default mixed-state qubit PennyLane plugin"
     short_name = "default.mixed"
     pennylane_requires = "0.15"
-    version = "0.15.0"
+    version = "0.15.1"
     author = "Xanadu Inc."
 
     operations = {
diff --git a/pennylane/devices/default_qubit.py b/pennylane/devices/default_qubit.py
index 35bfcddfb..fa50284a0 100644
--- a/pennylane/devices/default_qubit.py
+++ b/pennylane/devices/default_qubit.py
@@ -85,7 +85,7 @@ class DefaultQubit(QubitDevice):
     name = "Default qubit PennyLane plugin"
     short_name = "default.qubit"
     pennylane_requires = "0.15"
-    version = "0.15.0"
+    version = "0.15.1"
     author = "Xanadu Inc."
 
     operations = {
diff --git a/pennylane/devices/default_qubit_jax.py b/pennylane/devices/default_qubit_jax.py
index ef20d8669..e50997381 100644
--- a/pennylane/devices/default_qubit_jax.py
+++ b/pennylane/devices/default_qubit_jax.py
@@ -247,8 +247,8 @@ class DefaultQubitJax(DefaultQubit):
                 "The number of shots has to be explicitly set on the jax device "
                 "when using sample-based measurements. Since no shots are specified, "
                 "a default of 1000 shots is used.\n"
-                "This warning will replaced with an error in a future release.",
-                DeprecationWarning,
+                "This warning will be replaced with an error in a future release.",
+                UserWarning,
             )
 
         shots = self.shots or 1000
diff --git a/pennylane/interfaces/autograd.py b/pennylane/interfaces/autograd.py
index 409c29a5b..ec138282f 100644
--- a/pennylane/interfaces/autograd.py
+++ b/pennylane/interfaces/autograd.py
@@ -261,7 +261,8 @@ class AutogradInterface(AnnotatedQueue):
                     if dy.size > 1:
                         vhp = dy @ ddy @ hessian @ dy.T
                     else:
-                        vhp = np.squeeze(ddy @ hessian)
+                        vhp = ddy @ hessian
+                        vhp = vhp.flatten()
 
                     return vhp
 
diff --git a/pennylane/ops/cv.py b/pennylane/ops/cv.py
index 0539a0213..18d060791 100644
--- a/pennylane/ops/cv.py
+++ b/pennylane/ops/cv.py
@@ -710,7 +710,7 @@ class ThermalState(CVOperation):
 
 
 class GaussianState(CVOperation):
-    r"""pennylane.GaussianState(r, V, wires)
+    r"""pennylane.GaussianState(V, r, wires)
     Prepare subsystems in a given Gaussian state.
 
     **Details:**
@@ -720,9 +720,9 @@ class GaussianState(CVOperation):
     * Gradient recipe: None
 
     Args:
+        V (array): the :math:`2N\times 2N` (real and positive definite) covariance matrix
         r (array): a length :math:`2N` vector of means, of the
             form :math:`(\x_0,\dots,\x_{N-1},\p_0,\dots,\p_{N-1})`
-        V (array): the :math:`2N\times 2N` (real and positive definite) covariance matrix
     """
     num_wires = AnyWires
     num_params = 2
diff --git a/pennylane/qnode.py b/pennylane/qnode.py
index abf4e5505..eab6d06b4 100644
--- a/pennylane/qnode.py
+++ b/pennylane/qnode.py
@@ -157,7 +157,7 @@ class QNode:
                 "Detected 'shots' as an argument to the given quantum function. "
                 "The 'shots' argument name is reserved for overriding the number of shots "
                 "taken by the device. Its use outside of this context should be avoided.",
-                DeprecationWarning,
+                UserWarning,
             )
             self._qfunc_uses_shots_arg = True
         else:
diff --git a/pennylane/tape/jacobian_tape.py b/pennylane/tape/jacobian_tape.py
index 43cacf874..5cddd1205 100644
--- a/pennylane/tape/jacobian_tape.py
+++ b/pennylane/tape/jacobian_tape.py
@@ -685,6 +685,36 @@ class JacobianTape(QuantumTape):
             # parameters. Simply return an empty Hessian.
             return np.zeros((len(params), len(params)), dtype=float)
 
+        # The parameter-shift Hessian implementation currently only supports
+        # the two-term parameter-shift rule. Raise an error for unsupported operations.
+        supported_ops = (
+            "RX",
+            "RY",
+            "RZ",
+            "Rot",
+            "PhaseShift",
+            "ControlledPhaseShift",
+            "MultiRZ",
+            "PauliRot",
+            "U1",
+            "U2",
+            "U3",
+            "SingleExcitationMinus",
+            "SingleExcitationPlus",
+            "DoubleExcitationMinus",
+            "DoubleExcitationPlus",
+        )
+
+        for idx, info in self._par_info.items():
+            op = info["op"]
+
+            if idx in self.trainable_params and op.name not in supported_ops:
+                raise ValueError(
+                    f"The operation {op.name} is currently not supported for the "
+                    f"parameter-shift Hessian.\nPlease decompose the operation in your "
+                    f"QNode by replacing it with '{op.__str__().replace('(', '.decomposition(')}'"
+                )
+
         # some gradient methods need the device or the device wires
         options["device"] = device
         options["dev_wires"] = device.wires
diff --git a/pennylane/tape/tape.py b/pennylane/tape/tape.py
index 3c1585c00..a557370c5 100644
--- a/pennylane/tape/tape.py
+++ b/pennylane/tape/tape.py
@@ -648,11 +648,40 @@ class QuantumTape(AnnotatedQueue):
         self.trainable_params = {parameter_mapping[i] for i in self.trainable_params}
         self._par_info = {parameter_mapping[k]: v for k, v in self._par_info.items()}
 
-        for op in self._ops:
-            op.inverse = not op.inverse
+        for idx, op in enumerate(self._ops):
+            try:
+                self._ops[idx] = op.adjoint()
+            except NotImplementedError:
+                op.inverse = not op.inverse
 
         self._ops = list(reversed(self._ops))
 
+    def adjoint(self):
+        """Create a tape that is the adjoint of this one.
+
+        Adjointed tapes are the conjugated and transposed version of the
+        original tapes. Adjointed ops are equivalent to the inverted operation for unitary
+        gates.
+
+        Returns:
+            ~.QuantumTape: the adjointed tape
+        """
+        new_tape = self.copy(copy_operations=True)
+        qml.transforms.invisible(new_tape.inv)()
+
+        # the current implementation of the adjoint
+        # transform requires that the returned inverted object
+        # is automatically queued.
+        QuantumTape._lock.acquire()
+        try:
+            QueuingContext.append(new_tape)
+        except Exception as _:
+            QuantumTape._lock.release()
+            raise
+        QuantumTape._lock.release()
+
+        return new_tape
+
     # ========================================================
     # Parameter handling
     # ========================================================
diff --git a/pennylane/templates/embeddings/amplitude.py b/pennylane/templates/embeddings/amplitude.py
index f85c18dae..4a0eeb71b 100644
--- a/pennylane/templates/embeddings/amplitude.py
+++ b/pennylane/templates/embeddings/amplitude.py
@@ -131,7 +131,7 @@ class AmplitudeEmbedding(Operation):
         if pad is not None:
             warnings.warn(
                 "The pad argument will be replaced by the pad_with option in future versions of PennyLane.",
-                PendingDeprecationWarning,
+                UserWarning,
             )
             if pad_with is None:
                 pad_with = pad
@@ -143,6 +143,11 @@ class AmplitudeEmbedding(Operation):
         features = self._preprocess(features, wires, pad_with, normalize)
         super().__init__(features, wires=wires, do_queue=do_queue)
 
+    def adjoint(self):  # pylint: disable=arguments-differ
+        return qml.adjoint(qml.templates.MottonenStatePreparation)(
+            self.parameters[0], wires=self.wires
+        )
+
     def expand(self):
 
         with qml.tape.QuantumTape() as tape:
diff --git a/pennylane/templates/layers/particle_conserving_u1.py b/pennylane/templates/layers/particle_conserving_u1.py
index 03008d6be..097f1bfd5 100644
--- a/pennylane/templates/layers/particle_conserving_u1.py
+++ b/pennylane/templates/layers/particle_conserving_u1.py
@@ -266,13 +266,14 @@ class ParticleConservingU1(Operation):
 
         with qml.tape.QuantumTape() as tape:
 
-            qml.BasisState(self.init_state, wires=self.wires)
+            qml.templates.BasisEmbedding(self.init_state, wires=self.wires)
 
             for l in range(self.n_layers):
                 for i, wires_ in enumerate(nm_wires):
                     u1_ex_gate(
                         self.parameters[0][l, i, 0], self.parameters[0][l, i, 1], wires=wires_
                     )
+
         return tape
 
     @staticmethod
diff --git a/pennylane/templates/layers/particle_conserving_u2.py b/pennylane/templates/layers/particle_conserving_u2.py
index 940e0c320..e0ac00a8a 100644
--- a/pennylane/templates/layers/particle_conserving_u2.py
+++ b/pennylane/templates/layers/particle_conserving_u2.py
@@ -183,7 +183,7 @@ class ParticleConservingU2(Operation):
 
         with qml.tape.QuantumTape() as tape:
 
-            qml.BasisState(self.init_state, wires=self.wires)
+            qml.templates.BasisEmbedding(self.init_state, wires=self.wires)
 
             for l in range(self.n_layers):
 
diff --git a/pennylane/transforms/adjoint.py b/pennylane/transforms/adjoint.py
index ea8908c2b..fbdb6e578 100644
--- a/pennylane/transforms/adjoint.py
+++ b/pennylane/transforms/adjoint.py
@@ -18,34 +18,51 @@ from pennylane.tape import QuantumTape, get_active_tape
 
 
 def adjoint(fn):
-    """Create a function that applies the adjoint of the provided operation or template.
+    """Create a function that applies the adjoint (inverse) of the provided operation or template.
 
     This transform can be used to apply the adjoint of an arbitrary sequence of operations.
 
     Args:
-        fn (function): Any python function that applies pennylane operations.
+        fn (function): A quantum function that applies quantum operations.
 
     Returns:
         function: A new function that will apply the same operations but adjointed and in reverse order.
 
     **Example**
 
+    The adjoint transforms can be used within a QNode to apply the adjoint of
+    any quantum function. Consider the following quantum function, that applies two
+    operations:
+
     .. code-block:: python3
 
-        def my_ops():
-            qml.RX(0.123, wires=0)
-            qml.RY(0.456, wires=0)
+        def my_ops(a, b, wire):
+            qml.RX(a, wires=wire)
+            qml.RY(b, wires=wire)
+
+    We can create a QNode that applies this quantum function,
+    followed by the adjoint of this function:
+
+    .. code-block:: python3
+
+        dev = qml.device('default.qubit', wires=1)
+
+        @qml.qnode(dev)
+        def circuit(a, b):
+            my_ops(a, b, wire=0)
+            qml.adjoint(my_ops)(a, b, wire=0)
+            return qml.expval(qml.PauliZ(0))
+
+    Printing this out, we can see that the inverse quantum
+    function has indeed been applied:
 
-        with qml.tape.QuantumTape() as tape:
-            my_ops()
+    >>> print(qml.draw(circuit)(0.2, 0.5))
+     0: ──RX(0.2)──RY(0.5)──RY(-0.5)──RX(-0.2)──┤ ⟨Z⟩
 
-        with qml.tape.QuantumTape() as tape_adj:
-            qml.adjoint(my_ops)()
+    The adjoint function can also be applied directly to templates and operations:
 
-    >>> print(tape.operations)
-    [RX(0.123, wires=[0]), RY(0.456, wires=[0])]
-    >>> print(tape_adj.operatioins)
-    [RY(-0.456, wires=[0]), RX(-0.123, wires=[0])]
+    >>> qml.adjoint(qml.RX)(0.123, wires=0)
+    >>> qml.adjoint(qml.templates.StronglyEntanglingLayers)(weights, wires=[0, 1])
 
     .. UsageDetails::
 
@@ -102,9 +119,10 @@ def adjoint(fn):
             try:
                 op.adjoint()
             except NotImplementedError:
-                # Decompose the operation and adjoint the result.
+                # Expand the operation and adjoint the result.
                 # We do not do anything with the output since
-                # decomposition will automatically queue the new operations.
-                adjoint(op.decomposition)(wires=op.wires)
+                # calling adjoint on the expansion will automatically
+                # queue the new operations.
+                adjoint(op.expand)()
 
     return wrapper
diff --git a/pennylane/utils.py b/pennylane/utils.py
index a2b15e094..258b7f6bf 100644
--- a/pennylane/utils.py
+++ b/pennylane/utils.py
@@ -305,8 +305,9 @@ def inv(operation_list):
             "Please use inv on the function including its arguments, as in inv(template(args))."
         )
     elif isinstance(operation_list, qml.tape.QuantumTape):
-        operation_list.inv()
-        return operation_list
+        new_tape = operation_list.adjoint()
+        return new_tape
+
     elif not isinstance(operation_list, Iterable):
         raise ValueError("The provided operation_list is not iterable.")
 
@@ -334,13 +335,13 @@ def inv(operation_list):
             # exist on the queuing context
             pass
 
-    with qml.tape.QuantumTape() as tape:
+    def qfunc():
         for o in operation_list:
             o.queue()
-            if o.inverse:
-                o.inv()
 
-    tape.inv()
+    with qml.tape.QuantumTape() as tape:
+        qml.adjoint(qfunc)()
+
     return tape
 
 
diff --git a/pennylane/vqe/vqe.py b/pennylane/vqe/vqe.py
index fe1292308..66e479b3b 100644
--- a/pennylane/vqe/vqe.py
+++ b/pennylane/vqe/vqe.py
@@ -547,7 +547,7 @@ class VQECost(ExpvalCost):
     def __init__(self, *args, **kwargs):
         warnings.warn(
             "Use of VQECost is deprecated and should be replaced with ExpvalCost",
-            DeprecationWarning,
+            UserWarning,
             2,
         )
         super().__init__(*args, **kwargs)
diff --git a/qchem/CHANGELOG.md b/qchem/CHANGELOG.md
index d60c21fa5..5ba82fa8d 100644
--- a/qchem/CHANGELOG.md
+++ b/qchem/CHANGELOG.md
@@ -1,3 +1,16 @@
+# Release 0.15.1
+
+<h3>Bug fixes</h3>
+
+* The version requirement for PySCF has been modified to allow for `pyscf>=1.7.2`.
+  [(#1254)](https://github.com/PennyLaneAI/pennylane/pull/1254)
+
+<h3>Contributors</h3>
+
+This release contains contributions from (in alphabetical order):
+
+Antal Száva.
+
 # Release 0.15.0
 
 <h3>Breaking changes</h3>
diff --git a/qchem/pennylane_qchem/_version.py b/qchem/pennylane_qchem/_version.py
index e631771f2..cb401c827 100644
--- a/qchem/pennylane_qchem/_version.py
+++ b/qchem/pennylane_qchem/_version.py
@@ -16,4 +16,4 @@
 Version number (major.minor.patch[-label])
 """
 
-__version__ = "0.15.0"
+__version__ = "0.15.1"
diff --git a/qchem/requirements.txt b/qchem/requirements.txt
index 453141b0c..5b4d19532 100644
--- a/qchem/requirements.txt
+++ b/qchem/requirements.txt
@@ -3,5 +3,5 @@ scipy
 pennylane>=0.13.0
 openfermion==1.0
 openfermionpsi4==0.5
-pyscf==1.7.2
+pyscf>=1.7.2
 openfermionpyscf==0.5
diff --git a/qchem/setup.py b/qchem/setup.py
index 7e4dbee98..18618fbac 100644
--- a/qchem/setup.py
+++ b/qchem/setup.py
@@ -22,7 +22,7 @@ requirements = [
     "openfermion>=1.0",
     "openfermionpyscf>=0.5; platform_system != 'Windows'",
     "openfermionpsi4>=0.5",
-    "pyscf==1.7.2; platform_system != 'Windows'",
+    "pyscf>=1.7.2; platform_system != 'Windows'",
 ]
 
 info = {


Test patch:
diff --git a/pennylane/devices/tests/conftest.py b/pennylane/devices/tests/conftest.py
index 686d76b46..a748006be 100755
--- a/pennylane/devices/tests/conftest.py
+++ b/pennylane/devices/tests/conftest.py
@@ -67,7 +67,7 @@ def skip_if():
     """Fixture to skip tests."""
 
     def _skip_if(dev, capabilities):
-        """ Skip test if device has any of the given capabilities. """
+        """Skip test if device has any of the given capabilities."""
 
         dev_capabilities = dev.capabilities()
         for capability, value in capabilities.items():
diff --git a/pennylane/devices/tests/test_properties.py b/pennylane/devices/tests/test_properties.py
index bebce8bd0..c833da422 100755
--- a/pennylane/devices/tests/test_properties.py
+++ b/pennylane/devices/tests/test_properties.py
@@ -39,7 +39,7 @@ except ImportError:
 
 
 def qfunc_no_input():
-    """Model agnostic quantum function """
+    """Model agnostic quantum function"""
     return qml.expval(qml.Identity(wires=0))
 
 
diff --git a/tests/circuit_drawer/test_circuit_drawer.py b/tests/circuit_drawer/test_circuit_drawer.py
index efb7b92c2..ef4511225 100644
--- a/tests/circuit_drawer/test_circuit_drawer.py
+++ b/tests/circuit_drawer/test_circuit_drawer.py
@@ -412,7 +412,7 @@ def wide_cv_qnode():
 
     def qfunc():
         qml.GaussianState(
-            np.array([(2 * i + 2) // 2 for i in range(16)]), 2 * np.eye(16), wires=list(range(8))
+            2 * np.eye(16), np.array([(2 * i + 2) // 2 for i in range(16)]), wires=list(range(8))
         )
         [qml.Beamsplitter(0.4, 0, wires=[2 * i, 2 * i + 1]) for i in range(4)]
         [qml.Beamsplitter(0.25475, 0.2312344, wires=[i, i + 4]) for i in range(4)]
@@ -441,8 +441,6 @@ def drawn_wide_cv_qnode():
         + " 6: ──├Gaussian(M0,M1)──╭BS(0.4, 0)──│──────────────────╰BS(0.255, 0.231)──────────────────────────────────────────╰│┤ ⟨|1,1╳1,1|⟩ \n"
         + " 7: ──╰Gaussian(M0,M1)──╰BS(0.4, 0)──╰BS(0.255, 0.231)──────────────────────────────────────────────────────────────╰┤ ⟨|1,1╳1,1|⟩ \n"
         + "M0 =\n"
-        + "[ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16]\n"
-        + "M1 =\n"
         + "[[2. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n"
         + " [0. 2. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n"
         + " [0. 0. 2. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n"
@@ -459,6 +457,8 @@ def drawn_wide_cv_qnode():
         + " [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2. 0. 0.]\n"
         + " [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2. 0.]\n"
         + " [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.]]\n"
+        + "M1 =\n"
+        + "[ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16]\n"
     )
 
 
@@ -468,7 +468,7 @@ def parameterized_cv_qnode():
 
     def qfunc(a, b, c, d, e, f):
         qml.ThermalState(3, wires=[1])
-        qml.GaussianState(np.array([1, 1, 1, 2, 2, 3, 3, 3]), 2 * np.eye(8), wires=[0, 1, 2, 3])
+        qml.GaussianState(2 * np.eye(8), np.array([1, 1, 1, 2, 2, 3, 3, 3]), wires=[0, 1, 2, 3])
         qml.Rotation(a, wires=0)
         qml.Rotation(b, wires=1)
         qml.Beamsplitter(d, 1, wires=[0, 1])
@@ -528,8 +528,6 @@ def drawn_parameterized_cv_qnode_with_values():
         + " 2: ──────────────├Gaussian(M0,M1)───────────────────────────╰BS(0.5, 1)──S(2.3, 0)──╰BS(2.76, 1)──╭BS(0.5, 1)──│─────────╰C───────│────────────╭┤ ⟨|1,5╳1,5|⟩       \n"
         + " 3: ──────────────╰Gaussian(M0,M1)──D(0.6, 0)──────────────────────────────────────────────────────╰BS(0.5, 1)──╰S(2, 2)───────────╰X(2)────────╰┤ ⟨|1,5╳1,5|⟩       \n"
         + "M0 =\n"
-        + "[1 1 1 2 2 3 3 3]\n"
-        + "M1 =\n"
         + "[[2. 0. 0. 0. 0. 0. 0. 0.]\n"
         + " [0. 2. 0. 0. 0. 0. 0. 0.]\n"
         + " [0. 0. 2. 0. 0. 0. 0. 0.]\n"
@@ -538,6 +536,8 @@ def drawn_parameterized_cv_qnode_with_values():
         + " [0. 0. 0. 0. 0. 2. 0. 0.]\n"
         + " [0. 0. 0. 0. 0. 0. 2. 0.]\n"
         + " [0. 0. 0. 0. 0. 0. 0. 2.]]\n"
+        + "M1 =\n"
+        + "[1 1 1 2 2 3 3 3]\n"
     )
 
 
diff --git a/tests/circuit_drawer/test_representation_resolver.py b/tests/circuit_drawer/test_representation_resolver.py
index df4fc75ea..e1c4eebbf 100644
--- a/tests/circuit_drawer/test_representation_resolver.py
+++ b/tests/circuit_drawer/test_representation_resolver.py
@@ -107,7 +107,7 @@ class TestRepresentationResolver:
             (qml.ControlledPhase(3.14, wires=[0, 1]), 0, "C"),
             (qml.ThermalState(3, wires=[1]), 1, "Thermal(3)"),
             (
-                qml.GaussianState(np.array([1, 2]), np.array([[2, 0], [0, 2]]), wires=[1]),
+                qml.GaussianState(np.array([[2, 0], [0, 2]]), np.array([1, 2]), wires=[1]),
                 1,
                 "Gaussian(M0,M1)",
             ),
@@ -242,7 +242,7 @@ class TestRepresentationResolver:
             (qml.ControlledPhase(3.14, wires=[0, 1]), 0, "C"),
             (qml.ThermalState(3, wires=[1]), 1, "Thermal(3)"),
             (
-                qml.GaussianState(np.array([1, 2]), np.array([[2, 0], [0, 2]]), wires=[1]),
+                qml.GaussianState(np.array([[2, 0], [0, 2]]), np.array([1, 2]), wires=[1]),
                 1,
                 "Gaussian(M0,M1)",
             ),
diff --git a/tests/devices/test_default_gaussian.py b/tests/devices/test_default_gaussian.py
index 92e5e7bce..685199a09 100644
--- a/tests/devices/test_default_gaussian.py
+++ b/tests/devices/test_default_gaussian.py
@@ -362,11 +362,13 @@ class TestDefaultGaussianDevice:
 
             if op.par_domain == 'A':
                 # the parameter is an array
-                if gate_name == 'GaussianState':
-                    p = [np.array([0.432, 0.123, 0.342, 0.123]), np.diag([0.5234]*4)]
+                if gate_name == "GaussianState":
+                    cov = np.diag([0.5234] * 4)
+                    mu = np.array([0.432, 0.123, 0.342, 0.123])
+                    p = [cov, mu]
                     w = list(range(2))
-                    expected_out = p
-                elif gate_name == 'Interferometer':
+                    expected_out = [mu, cov]
+                elif gate_name == "Interferometer":
                     w = list(range(2))
                     p = [U]
                     S = fn(*p)
@@ -721,8 +723,8 @@ class TestDefaultGaussianIntegration:
         # compare to reference result
         def reference(*x):
             """reference circuit"""
-            if g == 'GaussianState':
-                return x[0][0]
+            if g == "GaussianState":
+                return x[1][0]
 
             if g == 'Displacement':
                 alpha = x[0]*np.exp(1j*x[1])
@@ -740,9 +742,9 @@ class TestDefaultGaussianIntegration:
 
             return (S @ np.array([a.real, a.imag, 0, 0])*np.sqrt(2*hbar))[0]
 
-        if g == 'GaussianState':
-            p = [np.array([0.432, 0.123, 0.342, 0.123]), np.diag([0.5234]*4)]
-        elif g == 'Interferometer':
+        if g == "GaussianState":
+            p = [np.diag([0.5234] * 4), np.array([0.432, 0.123, 0.342, 0.123])]
+        elif g == "Interferometer":
             p = [U]
         else:
             p = [0.432423, -0.12312, 0.324, 0.763][:op.num_params]
diff --git a/tests/devices/test_default_mixed.py b/tests/devices/test_default_mixed.py
index 484fcf42f..fb523c082 100644
--- a/tests/devices/test_default_mixed.py
+++ b/tests/devices/test_default_mixed.py
@@ -162,7 +162,7 @@ class TestReset:
 
 @pytest.mark.parametrize("nr_wires", [1, 2, 3])
 class TestAnalyticProb:
-    """Unit tests for the method `analytic_probability()` """
+    """Unit tests for the method `analytic_probability()`"""
 
     def test_prob_init_state(self, nr_wires, tol):
         """Tests that we obtain the correct probabilities for the state |0...0><0...0|"""
diff --git a/tests/devices/test_default_qubit.py b/tests/devices/test_default_qubit.py
index 6ac9a75d3..078020431 100644
--- a/tests/devices/test_default_qubit.py
+++ b/tests/devices/test_default_qubit.py
@@ -1774,8 +1774,8 @@ class TestWiresIntegration:
         assert np.allclose(circuit1(), circuit2(), tol)
 
     def test_wires_not_found_exception(self):
-        """Tests that an exception is raised when wires not present on the device are adressed. """
-        dev = qml.device("default.qubit", wires=['a', 'b'])
+        """Tests that an exception is raised when wires not present on the device are adressed."""
+        dev = qml.device("default.qubit", wires=["a", "b"])
 
         with qml.tape.QuantumTape() as tape:
             qml.RX(0.5, wires='c')
@@ -1985,7 +1985,7 @@ class TestInverseDecomposition:
         test_s_inverse()
         operations = test_s_inverse.qtape.operations
         assert "S.inv" not in [i.name for i in operations]
-        assert "PhaseShift.inv" in [i.name for i in operations]
+        assert "PhaseShift" in [i.name for i in operations]
 
         expected = np.array([1., -1.j]) / np.sqrt(2)
         assert np.allclose(dev.state, expected, atol=tol, rtol=0)
diff --git a/tests/devices/test_default_qubit_jax.py b/tests/devices/test_default_qubit_jax.py
index 9d470fab9..c4876090f 100644
--- a/tests/devices/test_default_qubit_jax.py
+++ b/tests/devices/test_default_qubit_jax.py
@@ -179,13 +179,15 @@ class TestQNodeIntegration:
         def circuit():
             return qml.sample(qml.PauliZ(wires=0))
 
-        with pytest.deprecated_call():
+        with pytest.warns(
+            UserWarning, match="The number of shots has to be explicitly set on the jax device"
+        ):
             res = circuit()
 
         assert len(res) == 1000
 
     def test_gates_dont_crash(self):
-        """Test for gates that weren't covered by other tests. """
+        """Test for gates that weren't covered by other tests."""
         dev = qml.device("default.qubit.jax", wires=2, shots=1000)
         @qml.qnode(dev, interface="jax", diff_method="backprop")
         def circuit():
diff --git a/tests/interfaces/test_qnode_autograd.py b/tests/interfaces/test_qnode_autograd.py
index 08804db0a..0d6425dce 100644
--- a/tests/interfaces/test_qnode_autograd.py
+++ b/tests/interfaces/test_qnode_autograd.py
@@ -794,6 +794,46 @@ class TestQNode:
         ]
         assert np.allclose(hess, expected_hess, atol=tol, rtol=0)
 
+    def test_hessian_unused_parameter(self, dev_name, diff_method, mocker, tol):
+        """Test hessian calculation of a scalar valued QNode"""
+        if diff_method not in {"parameter-shift", "backprop"}:
+            pytest.skip("Test only supports parameter-shift or backprop")
+
+        dev = qml.device(dev_name, wires=1)
+
+        @qnode(dev, diff_method=diff_method, interface="autograd")
+        def circuit(x):
+            qml.RY(x[0], wires=0)
+            return qml.expval(qml.PauliZ(0))
+
+        x = np.array([1.0, 2.0], requires_grad=True)
+        res = circuit(x)
+
+        a, b = x
+
+        expected_res = np.cos(a)
+        assert np.allclose(res, expected_res, atol=tol, rtol=0)
+
+        grad_fn = qml.grad(circuit)
+        g = grad_fn(x)
+
+        expected_g = [-np.sin(a), 0]
+        assert np.allclose(g, expected_g, atol=tol, rtol=0)
+
+        spy = mocker.spy(JacobianTape, "hessian")
+        hess = qml.jacobian(grad_fn)(x)
+
+        if diff_method == "backprop":
+            spy.assert_not_called()
+        elif diff_method == "parameter-shift":
+            spy.assert_called_once()
+
+        expected_hess = [
+            [-np.cos(a), 0],
+            [0, 0],
+        ]
+        assert np.allclose(hess, expected_hess, atol=tol, rtol=0)
+
     def test_hessian_vector_valued(self, dev_name, diff_method, mocker, tol):
         """Test hessian calculation of a vector valued QNode"""
         if diff_method not in {"parameter-shift", "backprop"}:
diff --git a/tests/tape/test_qnode.py b/tests/tape/test_qnode.py
index 95cc689a0..77f9d8c86 100644
--- a/tests/tape/test_qnode.py
+++ b/tests/tape/test_qnode.py
@@ -875,7 +875,9 @@ class TestShots:
             qml.RX(a, wires=shots)
             return qml.sample(qml.PauliZ(wires=0))
 
-        with pytest.warns(DeprecationWarning, match="The 'shots' argument name is reserved for overriding"):
+        with pytest.warns(
+            UserWarning, match="The 'shots' argument name is reserved for overriding"
+        ):
             circuit = qml.QNode(circuit, dev)
 
         assert len(circuit(0.8)) == 10
@@ -899,7 +901,9 @@ class TestShots:
             return qml.sample(qml.PauliZ(wires=qml.numpy.array(0)))
 
         # assert that warning is still raised
-        with pytest.warns(DeprecationWarning, match="The 'shots' argument name is reserved for overriding"):
+        with pytest.warns(
+            UserWarning, match="The 'shots' argument name is reserved for overriding"
+        ):
             circuit = qml.QNode(circuit, dev)
 
         assert len(circuit(0.8, 1)) == 10
diff --git a/tests/tape/test_qubit_param_shift.py b/tests/tape/test_qubit_param_shift.py
index 89097ee9d..a3b4969dd 100644
--- a/tests/tape/test_qubit_param_shift.py
+++ b/tests/tape/test_qubit_param_shift.py
@@ -580,7 +580,7 @@ class TestHessian:
         assert np.allclose(autograd_val, manualgrad_val, atol=tol, rtol=0)
 
     def test_vector_output(self, tol):
-        """Tests that a vector valued output tape has a hessian with the proper result. """
+        """Tests that a vector valued output tape has a hessian with the proper result."""
 
         dev = qml.device('default.qubit', wires=1)
 
@@ -620,3 +620,65 @@ class TestHessian:
         hessian = tape.hessian(dev)
 
         assert hessian.shape == (0, 0)
+
+    @pytest.mark.parametrize("G", [qml.CRX, qml.CRY, qml.CRZ])
+    def test_controlled_rotation_error(self, G, tol):
+        """Test that attempting to perform the parameter-shift rule on the controlled rotation gates
+        results in an error."""
+        dev = qml.device("default.qubit", wires=2)
+        b = 0.123
+
+        with QubitParamShiftTape() as tape:
+            qml.QubitStateVector(np.array([1.0, -1.0]) / np.sqrt(2), wires=0)
+            G(b, wires=[0, 1])
+            qml.expval(qml.PauliX(0))
+
+        tape.trainable_params = {1}
+
+        res = tape.execute(dev)
+        assert np.allclose(res, -np.cos(b / 2), atol=tol, rtol=0)
+
+        with pytest.raises(ValueError, match="not supported for the parameter-shift Hessian"):
+            tape.hessian(dev, method="analytic")
+
+    @pytest.mark.parametrize("G", [qml.CRX, qml.CRY, qml.CRZ])
+    def test_controlled_rotation_second_derivative(self, G, tol):
+        """Test that the controlled rotation gates return the correct
+        second derivative if first decomposed."""
+        dev = qml.device("default.qubit", wires=2)
+        init_state = qml.numpy.array([1.0, -1.0], requires_grad=False) / np.sqrt(2)
+
+        @qml.qnode(dev)
+        def circuit(b):
+            qml.QubitStateVector(init_state, wires=0)
+            G(b, wires=[0, 1])
+            return qml.expval(qml.PauliX(0))
+
+        b = 0.123
+
+        res = circuit(b)
+        assert np.allclose(res, -np.cos(b / 2), atol=tol, rtol=0)
+
+        grad = qml.grad(qml.grad(circuit))(b)
+        expected = np.cos(b / 2) / 4
+        assert np.allclose(grad, expected, atol=tol, rtol=0)
+
+    def test_non_differentiable_controlled_rotation(self, tol):
+        """Tests that a non-differentiable controlled operation does not affect
+        the Hessian computation."""
+
+        dev = qml.device("default.qubit", wires=2)
+
+        x = 0.6
+
+        with QubitParamShiftTape() as tape:
+            qml.RY(x, wires=0)
+            qml.CRY(np.pi / 2, wires=[0, 1])
+            qml.expval(qml.PauliX(0))
+
+        tape.trainable_params = {0}
+        hess = tape.hessian(dev)
+
+        expected_hess = np.array([-np.sin(x) / np.sqrt(2)])
+
+        assert np.allclose(hess, expected_hess, atol=tol, rtol=0)
diff --git a/tests/tape/test_tape.py b/tests/tape/test_tape.py
index 9ae9f155b..2508de02a 100644
--- a/tests/tape/test_tape.py
+++ b/tests/tape/test_tape.py
@@ -604,12 +604,10 @@ class TestInverse:
         tape.inv()
 
         # check that operation order is reversed
-        assert tape.operations == [prep] + ops[::-1]
+        assert [o.name for o in tape.operations] == ["BasisState", "CNOT", "Rot", "RX"]
 
         # check that operations are inverted
-        assert ops[0].inverse
-        assert not ops[1].inverse
-        assert ops[2].inverse
+        assert np.allclose(tape.operations[2].parameters, -np.array(p[-1:0:-1]))
 
         # check that parameter order has reversed
         assert tape.get_parameters() == [init_state, p[1], p[2], p[3], p[0]]
@@ -636,7 +634,7 @@ class TestInverse:
         tape.inv()
         assert tape.trainable_params == {1, 2}
         assert tape.get_parameters() == [p[0], p[1]]
-        assert tape._ops == ops
+        assert [o.name for o in tape._ops] == ["RX", "Rot", "CNOT"]
 
 
 class TestExpand:
diff --git a/tests/templates/test_embeddings/test_amplitude.py b/tests/templates/test_embeddings/test_amplitude.py
index baf265d36..1b53a3650 100644
--- a/tests/templates/test_embeddings/test_amplitude.py
+++ b/tests/templates/test_embeddings/test_amplitude.py
@@ -239,7 +239,7 @@ class TestInputs:
             return qml.expval(qml.PauliZ(0))
 
         with pytest.warns(
-            PendingDeprecationWarning,
+            UserWarning,
             match="will be replaced by the pad_with option in future versions",
         ):
             circuit(x=inputs)
diff --git a/tests/templates/test_layers/test_particle_conserving_u1.py b/tests/templates/test_layers/test_particle_conserving_u1.py
index a7d64976d..d65936b18 100644
--- a/tests/templates/test_layers/test_particle_conserving_u1.py
+++ b/tests/templates/test_layers/test_particle_conserving_u1.py
@@ -84,7 +84,7 @@ class TestDecomposition:
         assert gate_count == len(queue)
 
         # check initialization of the qubit register
-        assert isinstance(queue[0], qml.BasisState)
+        assert isinstance(queue[0], qml.templates.BasisEmbedding)
 
         # check all quantum operations
         idx_CRot = 8
diff --git a/tests/templates/test_layers/test_particle_conserving_u2.py b/tests/templates/test_layers/test_particle_conserving_u2.py
index f741956a5..3a05f8e2d 100644
--- a/tests/templates/test_layers/test_particle_conserving_u2.py
+++ b/tests/templates/test_layers/test_particle_conserving_u2.py
@@ -50,7 +50,7 @@ class TestDecomposition:
         assert len(queue) == n_gates
 
         # initialization
-        assert isinstance(queue[0], qml.BasisState)
+        assert isinstance(queue[0], qml.templates.BasisEmbedding)
 
         # order of gates
         for op1, op2 in zip(queue[1:], exp_gates):
diff --git a/tests/templates/test_subroutines/test_permute.py b/tests/templates/test_subroutines/test_permute.py
index f0b2408cd..a33d5c063 100644
--- a/tests/templates/test_subroutines/test_permute.py
+++ b/tests/templates/test_subroutines/test_permute.py
@@ -23,7 +23,7 @@ class TestDecomposition:
     """Tests that the template defines the correct decomposition."""
 
     def test_identity_permutation_qnode(self):
-        """ Test that identity permutations have no effect on QNodes. """
+        """Test that identity permutations have no effect on QNodes."""
 
         dev = qml.device("default.qubit", wires=4)
 
@@ -40,7 +40,7 @@ class TestDecomposition:
         assert len(tape.operations) == 0
 
     def test_identity_permutation_tape(self):
-        """ Test that identity permutations have no effect on tapes. """
+        """Test that identity permutations have no effect on tapes."""
 
         with qml.tape.QuantumTape() as tape:
             qml.templates.Permute([0, "a", "c", "d"], wires=[0, "a", "c", "d"])
@@ -61,7 +61,7 @@ class TestDecomposition:
         ],
     )
     def test_two_cycle_permutations_qnode(self, permutation_order, expected_wires):
-        """ Test some two-cycles on QNodes. """
+        """Test some two-cycles on QNodes."""
 
         dev = qml.device("default.qubit", wires=len(permutation_order))
 
@@ -92,7 +92,7 @@ class TestDecomposition:
         ],
     )
     def test_two_cycle_permutations_tape(self, permutation_order, wire_order, expected_wires):
-        """ Test some two-cycles on tapes. """
+        """Test some two-cycles on tapes."""
 
         with qml.tape.QuantumTape() as tape:
             qml.templates.Permute(permutation_order, wire_order)
@@ -113,7 +113,7 @@ class TestDecomposition:
         ],
     )
     def test_cyclic_permutations_qnode(self, permutation_order, expected_wires):
-        """ Test more general cycles on QNodes. """
+        """Test more general cycles on QNodes."""
 
         dev = qml.device("default.qubit", wires=len(permutation_order))
 
@@ -140,7 +140,7 @@ class TestDecomposition:
         ],
     )
     def test_cyclic_permutations_tape(self, permutation_order, wire_order, expected_wires):
-        """ Test more general cycles on tapes. """
+        """Test more general cycles on tapes."""
 
         with qml.tape.QuantumTape() as tape:
             qml.templates.Permute(permutation_order, wire_order)
@@ -161,7 +161,7 @@ class TestDecomposition:
         ],
     )
     def test_arbitrary_permutations_qnode(self, permutation_order, expected_wires):
-        """ Test arbitrarily generated permutations on QNodes. """
+        """Test arbitrarily generated permutations on QNodes."""
 
         dev = qml.device("default.qubit", wires=len(permutation_order))
 
@@ -196,7 +196,7 @@ class TestDecomposition:
         ],
     )
     def test_arbitrary_permutations_tape(self, permutation_order, wire_order, expected_wires):
-        """ Test arbitrarily generated permutations on tapes. """
+        """Test arbitrarily generated permutations on tapes."""
 
         with qml.tape.QuantumTape() as tape:
             qml.templates.Permute(permutation_order, wire_order)
@@ -219,7 +219,7 @@ class TestDecomposition:
     def test_subset_permutations_qnode(
         self, num_wires, permutation_order, wire_subset, expected_wires
     ):
-        """ Test permutation of wire subsets on QNodes. """
+        """Test permutation of wire subsets on QNodes."""
 
         dev = qml.device("default.qubit", wires=num_wires)
 
@@ -253,7 +253,7 @@ class TestDecomposition:
     def test_subset_permutations_tape(
         self, wire_labels, permutation_order, wire_subset, expected_wires
     ):
-        """ Test permutation of wire subsets on tapes. """
+        """Test permutation of wire subsets on tapes."""
 
         with qml.tape.QuantumTape() as tape:
             # Make sure all the wires are actually there
diff --git a/tests/test_operation.py b/tests/test_operation.py
index 34437c5e8..29ed19170 100644
--- a/tests/test_operation.py
+++ b/tests/test_operation.py
@@ -459,7 +459,7 @@ class TestObservableConstruction:
 
 
 class TestOperatorIntegration:
-    """ Integration tests for the Operator class"""
+    """Integration tests for the Operator class"""
 
     def test_all_wires_defined_but_init_with_one(self):
         """Test that an exception is raised if the class is defined with ALL wires,
@@ -486,7 +486,7 @@ class TestOperatorIntegration:
 
 
 class TestOperationIntegration:
-    """ Integration tests for the Operation class"""
+    """Integration tests for the Operation class"""
 
     def test_inverse_of_operation(self):
         """Test the inverse of an operation"""
diff --git a/tests/test_qubit_device.py b/tests/test_qubit_device.py
index 94ec3b94a..0d5b107b9 100644
--- a/tests/test_qubit_device.py
+++ b/tests/test_qubit_device.py
@@ -35,7 +35,7 @@ mock_qubit_device_rotations = ["RX", "RY", "RZ"]
 
 @pytest.fixture(scope="function")
 def mock_qubit_device(monkeypatch):
-    """ A function to create a mock device that mocks most of the methods except for e.g. probability()"""
+    """A function to create a mock device that mocks most of the methods except for e.g. probability()"""
     with monkeypatch.context() as m:
         m.setattr(QubitDevice, "__abstractmethods__", frozenset())
         m.setattr(QubitDevice, "_capabilities", mock_qubit_device_capabilities)
@@ -413,7 +413,9 @@ class TestSampleBasisStates:
         dev.shots = None
         state_probs = [0.1, 0.2, 0.3, 0.4]
 
-        with pytest.warns(DeprecationWarning, match="The number of shots has to be explicitly set on the device"):
+        with pytest.warns(
+            UserWarning, match="The number of shots has to be explicitly set on the device"
+        ):
             dev.sample_basis_states(number_of_states, state_probs)
 
 
diff --git a/tests/test_utils.py b/tests/test_utils.py
index f3efe45b3..83291cc8b 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -462,8 +462,8 @@ def inverted_dummy_template_operations(wires):
     ops = []
 
     for wire in reversed(wires):
-        ops.append(qml.RY(-1, wires=[wire]).inv())
-        ops.append(qml.RX(1, wires=[wire]).inv())
+        ops.append(qml.RY(1, wires=[wire]))
+        ops.append(qml.RX(-1, wires=[wire]))
 
     return ops
 
@@ -474,7 +474,7 @@ class TestInv:
     def test_inversion_without_context(self):
         """Test that a sequence of operations is properly inverted."""
         op_queue = [qml.PauliX(0), qml.PauliY(0).inv(), qml.PauliZ(0)]
-        inv_queue = [qml.PauliZ(0).inv(), qml.PauliY(0), qml.PauliX(0).inv()]
+        inv_queue = [qml.PauliZ(0), qml.PauliY(0), qml.PauliX(0)]
 
         inv_ops = pu.inv(op_queue).operations
 
@@ -526,9 +526,9 @@ class TestInv:
         inv_queue = [
             qml.Hadamard(wires=[0]),
             qml.CNOT(wires=[0, 1]),
-            qml.RZ(3, wires=[0]).inv(),
-            qml.RY(2, wires=[0]).inv(),
-            qml.RX(1, wires=[0]).inv(),
+            qml.RZ(-3, wires=[0]),
+            qml.RY(-2, wires=[0]),
+            qml.RX(-1, wires=[0]),
             qml.CNOT(wires=[0, 1]),
             qml.Hadamard(wires=[0]),
         ]
@@ -553,9 +553,9 @@ class TestInv:
         inv_queue = [
             qml.Hadamard(wires=[0]),
             qml.CNOT(wires=[0, 1]),
-            qml.RZ(3, wires=[0]).inv(),
-            qml.RY(2, wires=[0]).inv(),
-            qml.RX(1, wires=[0]).inv(),
+            qml.RZ(-3, wires=[0]),
+            qml.RY(-2, wires=[0]),
+            qml.RX(-1, wires=[0]),
             qml.CNOT(wires=[0, 1]),
             qml.Hadamard(wires=[0]),
         ]
@@ -581,10 +581,10 @@ class TestInv:
         inv_queue = [
             qml.Hadamard(wires=[0]),
             qml.CNOT(wires=[0, 1]),
-            qml.RY(2, wires=[0]).inv(),
-            qml.PauliZ(0).inv(),
-            qml.RX(1, wires=[0]).inv(),
-            qml.PauliX(0).inv(),
+            qml.RY(-2, wires=[0]),
+            qml.PauliZ(0),
+            qml.RX(-1, wires=[0]),
+            qml.PauliX(0),
             qml.CNOT(wires=[0, 1]),
             qml.Hadamard(wires=[0]),
         ]
@@ -611,10 +611,10 @@ class TestInv:
         inv_queue = [
             qml.Hadamard(wires=[0]),
             qml.CNOT(wires=[0, 1]),
-            qml.RY(2, wires=[0]).inv(),
-            qml.PauliZ(0).inv(),
-            qml.RX(1, wires=[0]).inv(),
-            qml.PauliX(0).inv(),
+            qml.RY(-2, wires=[0]),
+            qml.PauliZ(0),
+            qml.RX(-1, wires=[0]),
+            qml.PauliX(0),
             qml.CNOT(wires=[0, 1]),
             qml.Hadamard(wires=[0]),
         ]
@@ -668,9 +668,9 @@ class TestInv:
         inv_queue = [
             qml.Hadamard(wires=[0]),
             qml.CNOT(wires=[0, 1]),
-            qml.RZ(3, wires=[0]).inv(),
-            qml.RY(2, wires=[0]).inv(),
-            qml.RX(1, wires=[0]).inv(),
+            qml.RZ(-3, wires=[0]),
+            qml.RY(-2, wires=[0]),
+            qml.RX(-1, wires=[0]),
             qml.CNOT(wires=[0, 1]),
             qml.Hadamard(wires=[0]),
         ]
@@ -702,9 +702,9 @@ class TestInv:
         inv_queue = [
             qml.Hadamard(wires=[0]),
             qml.CNOT(wires=[0, 1]),
-            qml.RZ(3, wires=[0]).inv(),
-            qml.RY(2, wires=[0]).inv(),
-            qml.RX(1, wires=[0]).inv(),
+            qml.RZ(-3, wires=[0]),
+            qml.RY(-2, wires=[0]),
+            qml.RX(-1, wires=[0]),
             qml.CNOT(wires=[0, 1]),
             qml.Hadamard(wires=[0]),
         ]
@@ -736,10 +736,10 @@ class TestInv:
         inv_queue = [
             qml.Hadamard(wires=[0]),
             qml.CNOT(wires=[0, 1]),
-            qml.RY(2, wires=[0]).inv(),
-            qml.PauliZ(0).inv(),
-            qml.RX(1, wires=[0]).inv(),
-            qml.PauliX(0).inv(),
+            qml.RY(-2, wires=[0]),
+            qml.PauliZ(0),
+            qml.RX(-1, wires=[0]),
+            qml.PauliX(0),
             qml.CNOT(wires=[0, 1]),
             qml.Hadamard(wires=[0]),
         ]
@@ -782,8 +782,8 @@ class TestInv:
 
     def test_argument_wrapping(self):
         """Test that a single operation can be given to inv and is properly inverted."""
-        op = qml.PauliX(0)
-        exp_op = qml.PauliX(0).inv()
+        op = qml.RX(0.1, wires=0)
+        exp_op = qml.RX(-0.1, wires=0)
 
         inv_ops = pu.inv(op).operations
 
diff --git a/tests/test_vqe.py b/tests/test_vqe.py
index 3e3b01109..37a45c26e 100644
--- a/tests/test_vqe.py
+++ b/tests/test_vqe.py
@@ -1203,13 +1203,13 @@ class TestMultipleInterfaceIntegration:
 
 
 def test_vqe_cost():
-    """Tests that VQECost raises a DeprecationWarning but otherwise behaves as ExpvalCost"""
+    """Tests that VQECost raises a UserWarning but otherwise behaves as ExpvalCost"""
 
     h = qml.Hamiltonian([1], [qml.PauliZ(0)])
     dev = qml.device("default.qubit", wires=1)
     ansatz = qml.templates.StronglyEntanglingLayers
 
-    with pytest.warns(DeprecationWarning, match="Use of VQECost is deprecated"):
+    with pytest.warns(UserWarning, match="Use of VQECost is deprecated"):
         cost = qml.VQECost(ansatz, h, dev)
 
     assert isinstance(cost, qml.ExpvalCost)
diff --git a/tests/transforms/test_adjoint.py b/tests/transforms/test_adjoint.py
index 0c17a25ed..c37696764 100644
--- a/tests/transforms/test_adjoint.py
+++ b/tests/transforms/test_adjoint.py
@@ -11,7 +11,7 @@
 # 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.
-
+import pytest
 import numpy as np
 
 import pennylane as qml
@@ -79,6 +79,294 @@ def test_nested_adjoint_on_function():
         return qml.state()
 
     np.testing.assert_allclose(
-        my_circuit(),
-        np.array([-0.995707,  0.068644+6.209710e-02j]),
-        atol=1e-6, rtol=1e-6)
+        my_circuit(), np.array([-0.995707, 0.068644 + 6.209710e-02j]), atol=1e-6, rtol=1e-6
+    )
+
+
+test_functions = [
+    lambda fn, *args, **kwargs: adjoint(fn)(*args, **kwargs),
+    lambda fn, *args, **kwargs: qml.inv(fn(*args, **kwargs)),
+]
+
+
+@pytest.mark.parametrize("fn", test_functions)
+class TestTemplateIntegration:
+    """Test that templates work correctly with the adjoint transform"""
+
+    def test_angle_embedding(self, fn):
+        """Test that the adjoint correctly inverts angle embedding"""
+        dev = qml.device("default.qubit", wires=3)
+        template = qml.templates.AngleEmbedding
+
+        @qml.qnode(dev)
+        def circuit(weights):
+            template(features=weights, wires=[0, 1, 2])
+            fn(template, features=weights, wires=[0, 1, 2])
+            return qml.state()
+
+        weights = np.array([0.2, 0.5, 0.8])
+        res = circuit(weights)
+        assert len(np.nonzero(res)) == 1
+
+    def test_amplitude_embedding(self, fn):
+        """Test that the adjoint correctly inverts amplitude embedding"""
+        dev = qml.device("default.qubit", wires=3)
+        template = qml.templates.AmplitudeEmbedding
+
+        @qml.qnode(dev)
+        def circuit(weights):
+            template(features=weights, wires=[0, 1, 2])
+            fn(template, features=weights, wires=[0, 1, 2])
+            return qml.state()
+
+        weights = np.array([0.2, 0.5, 0.8, 0.6, 0.1, 0.6, 0.1, 0.5]) / np.sqrt(1.92)
+        res = circuit(weights)
+        assert len(np.nonzero(res)) == 1
+
+    def test_basis_embedding(self, fn):
+        """Test that the adjoint correctly inverts basis embedding"""
+        dev = qml.device("default.qubit", wires=3)
+        template = qml.templates.BasisEmbedding
+
+        @qml.qnode(dev)
+        def circuit(weights):
+            template(features=weights, wires=[0, 1, 2])
+            fn(template, features=weights, wires=[0, 1, 2])
+            return qml.state()
+
+        weights = np.array([1, 0, 1])
+        res = circuit(weights)
+        expected = np.zeros([2 ** 3])
+        expected[0] = 1.0
+        assert np.allclose(res, expected)
+
+    def test_displacement_embedding(self, fn):
+        """Test that the adjoint correctly inverts displacement embedding"""
+        dev = qml.device("default.gaussian", wires=3)
+        template = qml.templates.DisplacementEmbedding
+
+        @qml.qnode(dev)
+        def circuit(weights):
+            template(features=weights, wires=[0, 1, 2])
+            fn(template, features=weights, wires=[0, 1, 2])
+            return qml.expval(qml.NumberOperator(0))
+
+        weights = np.array([0.6, 0.2, 0.1])
+        res = circuit(weights)
+        assert np.allclose(res, 0.0)
+
+    def test_squeezing_embedding(self, fn):
+        """Test that the adjoint correctly inverts squeezing embedding"""
+        dev = qml.device("default.gaussian", wires=3)
+        template = qml.templates.SqueezingEmbedding
+
+        @qml.qnode(dev)
+        def circuit(weights):
+            template(features=weights, wires=[0, 1, 2])
+            fn(template, features=weights, wires=[0, 1, 2])
+            return qml.expval(qml.NumberOperator(0))
+
+        weights = np.array([0.6, 0.2, 0.1])
+        res = circuit(weights)
+        assert np.allclose(res, 0.0)
+
+    def test_qaoa_embedding(self, fn):
+        """Test that the adjoint correctly inverts qaoa embedding"""
+        dev = qml.device("default.qubit", wires=3)
+        template = qml.templates.QAOAEmbedding
+
+        @qml.qnode(dev)
+        def circuit(features, weights):
+            template(features=features, weights=weights, wires=[0, 1, 2])
+            fn(template, features=features, weights=weights, wires=[0, 1, 2])
+            return qml.state()
+
+        features = np.array([1.0, 2.0, 3.0])
+        weights = np.random.random(template.shape(2, 3))
+
+        res = circuit(features, weights)
+        expected = np.zeros([2 ** 3])
+        expected[0] = 1.0
+
+        assert np.allclose(res, expected)
+
+    def test_iqp_embedding(self, fn):
+        """Test that the adjoint correctly inverts iqp embedding"""
+        dev = qml.device("default.qubit", wires=3)
+        template = qml.templates.IQPEmbedding
+
+        @qml.qnode(dev)
+        def circuit(features):
+            template(features=features, wires=[0, 1, 2])
+            fn(template, features=features, wires=[0, 1, 2])
+            return qml.state()
+
+        features = np.array([1.0, 2.0, 3.0])
+        res = circuit(features)
+        expected = np.zeros([2 ** 3])
+        expected[0] = 1.0
+
+        assert np.allclose(res, expected)
+
+    @pytest.mark.parametrize(
+        "template",
+        [
+            qml.templates.BasicEntanglerLayers,
+            qml.templates.StronglyEntanglingLayers,
+            qml.templates.RandomLayers,
+        ],
+    )
+    def test_layers(self, fn, template):
+        """Test that the adjoint correctly inverts layers"""
+        dev = qml.device("default.qubit", wires=3)
+
+        @qml.qnode(dev)
+        def circuit(weights):
+            template(weights=weights, wires=[0, 1, 2])
+            fn(template, weights=weights, wires=[0, 1, 2])
+            return qml.state()
+
+        weights = np.random.random(template.shape(2, 3))
+        res = circuit(weights)
+        expected = np.zeros([2 ** 3])
+        expected[0] = 1.0
+
+        assert np.allclose(res, expected)
+
+    @pytest.mark.parametrize(
+        "template",
+        [
+            qml.templates.ParticleConservingU1,
+            qml.templates.ParticleConservingU2,
+        ],
+    )
+    def test_particle_conserving(self, fn, template):
+        """Test that the adjoint correctly inverts particle conserving layers"""
+        dev = qml.device("default.qubit", wires=3)
+        init_state = np.array([0, 1, 1])
+
+        @qml.qnode(dev)
+        def circuit(weights):
+            template(weights=weights, init_state=init_state, wires=[0, 1, 2])
+            fn(template, weights=weights, init_state=init_state, wires=[0, 1, 2])
+            return qml.state()
+
+        weights = np.random.random(template.shape(2, 3))
+        res = circuit(weights)
+        expected = np.zeros([2 ** 3])
+        expected[0] = 1.0
+
+        assert np.allclose(res, expected)
+
+    def test_simplified_two_design(self, fn):
+        """Test that the adjoint correctly inverts the simplified two design"""
+        dev = qml.device("default.qubit", wires=3)
+        template = qml.templates.SimplifiedTwoDesign
+
+        @qml.qnode(dev)
+        def circuit(data, weights):
+            template(initial_layer_weights=data, weights=weights, wires=[0, 1, 2])
+            fn(template, initial_layer_weights=data, weights=weights, wires=[0, 1, 2])
+            return qml.state()
+
+        weights = [np.random.random(s) for s in template.shape(2, 3)]
+        res = circuit(weights[0], *weights[1:])
+        expected = np.zeros([2 ** 3])
+        expected[0] = 1.0
+
+        assert np.allclose(res, expected)
+
+    def test_approx_time_evolution(self, fn):
+        """Test that the adjoint correctly inverts the approx time evolution"""
+        dev = qml.device("default.qubit", wires=3)
+        template = qml.templates.ApproxTimeEvolution
+
+        coeffs = [1, 1]
+        obs = [qml.PauliX(0), qml.PauliX(1)]
+        H = qml.Hamiltonian(coeffs, obs)
+
+        @qml.qnode(dev)
+        def circuit(t):
+            template(H, t, 1)
+            fn(template, H, t, 1)
+            return qml.state()
+
+        res = circuit(0.5)
+        expected = np.zeros([2 ** 3])
+        expected[0] = 1.0
+        assert np.allclose(res, expected)
+
+    def test_arbitrary_unitary(self, fn):
+        """Test that the adjoint correctly inverts the arbitrary unitary"""
+        dev = qml.device("default.qubit", wires=3)
+        template = qml.templates.ArbitraryUnitary
+
+        @qml.qnode(dev)
+        def circuit(weights):
+            template(weights=weights, wires=[0, 1, 2])
+            fn(template, weights=weights, wires=[0, 1, 2])
+            return qml.state()
+
+        weights = np.random.random(template.shape(3))
+        res = circuit(weights)
+        expected = np.zeros([2 ** 3])
+        expected[0] = 1.0
+
+        assert np.allclose(res, expected)
+
+    def test_single_excitation(self, fn):
+        """Test that the adjoint correctly inverts the single excitation unitary"""
+        dev = qml.device("default.qubit", wires=3)
+        template = qml.templates.SingleExcitationUnitary
+
+        @qml.qnode(dev)
+        def circuit(weights):
+            template(weight=weights, wires=[0, 1, 2])
+            fn(template, weight=weights, wires=[0, 1, 2])
+            return qml.state()
+
+        res = circuit(0.6)
+        expected = np.zeros([2 ** 3])
+        expected[0] = 1.0
+
+        assert np.allclose(res, expected)
+
+    def test_double_excitation(self, fn):
+        """Test that the adjoint correctly inverts the double excitation unitary"""
+        dev = qml.device("default.qubit", wires=4)
+        template = qml.templates.DoubleExcitationUnitary
+
+        @qml.qnode(dev)
+        def circuit(weights):
+            template(weight=weights, wires1=[0, 1], wires2=[2, 3])
+            fn(template, weight=weights, wires1=[0, 1], wires2=[2, 3])
+            return qml.state()
+
+        res = circuit(0.6)
+        expected = np.zeros([2 ** 4])
+        expected[0] = 1.0
+
+        assert np.allclose(res, expected)
+
+    def test_interferometer(self, fn):
+        """Test that the adjoint correctly inverts squeezing embedding"""
+        dev = qml.device("default.gaussian", wires=3)
+        template = qml.templates.Interferometer
+        r = 1.5
+
+        @qml.qnode(dev)
+        def circuit(weights):
+            qml.Squeezing(r, 0, wires=0)
+            qml.Squeezing(r, 0, wires=1)
+            qml.Squeezing(r, 0, wires=2)
+            template(*weights, wires=[0, 1, 2])
+            fn(template, *weights, wires=[0, 1, 2])
+            return qml.expval(qml.NumberOperator(0))
+
+        weights = [
+            np.random.random([3 * (3 - 1) // 2]),
+            np.random.random([3 * (3 - 1) // 2]),
+            np.random.random([3]),
+        ]
+        res = circuit(weights)
+        assert np.allclose(res, np.sinh(r) ** 2)