Repository: PennyLaneAI/pennylane
Pull request #1438 (2021-06-29 11:29:15)

Add id attribute to templates
In PR #1377 an ID argument and attribute was added to the operator class, including generic tests for `Operation` and `Observable`. While the gates do not overwrite the `__init__` method, the templates do, and the `id` argument has to be added to every template, which has not been done yet. 

This PR makes the correction, and also adds a test to each template.

github-actions[bot]: Hello. You may have forgotten to update the changelog!
Please edit [.github/CHANGELOG.md](/PennyLaneAI/pennylane/blob/master/.github/CHANGELOG.md) with:
* A one-to-two sentence description of the change. You may include a small working example for new features.
* A link back to this PR.
* Your name (or GitHub username) in the contributors section.
codecov[bot]: # [Codecov](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1438?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) Report
> Merging [#1438](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1438?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) (bd57740) into [master](https://codecov.io/gh/PennyLaneAI/pennylane/commit/614db57b02536bb09fbfbae853ceff8878b928af?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) (614db57) will **not change** coverage.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1438/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/1438?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI)

```diff
@@           Coverage Diff           @@
##           master    #1438   +/-   ##
=======================================
  Coverage   98.23%   98.23%           
=======================================
  Files         160      160           
  Lines       11966    11966           
=======================================
  Hits        11755    11755           
  Misses        211      211           
```


| [Impacted Files](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1438?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) | Coverage Δ | |
|---|---|---|
| [pennylane/templates/layers/cv\_neural\_net.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1438/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3RlbXBsYXRlcy9sYXllcnMvY3ZfbmV1cmFsX25ldC5weQ==) | `100.00% <ø> (ø)` | |
| [pennylane/templates/embeddings/amplitude.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1438/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3RlbXBsYXRlcy9lbWJlZGRpbmdzL2FtcGxpdHVkZS5weQ==) | `100.00% <100.00%> (ø)` | |
| [pennylane/templates/embeddings/angle.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1438/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3RlbXBsYXRlcy9lbWJlZGRpbmdzL2FuZ2xlLnB5) | `100.00% <100.00%> (ø)` | |
| [pennylane/templates/embeddings/basis.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1438/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3RlbXBsYXRlcy9lbWJlZGRpbmdzL2Jhc2lzLnB5) | `100.00% <100.00%> (ø)` | |
| [pennylane/templates/embeddings/displacement.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1438/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3RlbXBsYXRlcy9lbWJlZGRpbmdzL2Rpc3BsYWNlbWVudC5weQ==) | `100.00% <100.00%> (ø)` | |
| [pennylane/templates/embeddings/iqp.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1438/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3RlbXBsYXRlcy9lbWJlZGRpbmdzL2lxcC5weQ==) | `100.00% <100.00%> (ø)` | |
| [pennylane/templates/embeddings/qaoa.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1438/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3RlbXBsYXRlcy9lbWJlZGRpbmdzL3Fhb2EucHk=) | `100.00% <100.00%> (ø)` | |
| [pennylane/templates/embeddings/squeezing.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1438/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3RlbXBsYXRlcy9lbWJlZGRpbmdzL3NxdWVlemluZy5weQ==) | `100.00% <100.00%> (ø)` | |
| [pennylane/templates/layers/basic\_entangler.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1438/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3RlbXBsYXRlcy9sYXllcnMvYmFzaWNfZW50YW5nbGVyLnB5) | `100.00% <100.00%> (ø)` | |
| [...nnylane/templates/layers/particle\_conserving\_u1.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1438/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3RlbXBsYXRlcy9sYXllcnMvcGFydGljbGVfY29uc2VydmluZ191MS5weQ==) | `100.00% <100.00%> (ø)` | |
| ... and [16 more](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1438/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/1438?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/1438?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI). Last update [614db57...bd57740](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1438?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).

mariaschuld: Thanks for picking this up @albi3ro, I totally forgot!

Patch:
diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md
index 16e4cc751..a3f567fe4 100644
--- a/.github/CHANGELOG.md
+++ b/.github/CHANGELOG.md
@@ -84,6 +84,10 @@
 
 <h3>Improvements</h3>
 
+* Added the `id` attribute to templates, which was missing from 
+  PR [(#1377)](https://github.com/PennyLaneAI/pennylane/pull/1377).
+  [(#1438)](https://github.com/PennyLaneAI/pennylane/pull/1438)
+  
 <h3>Breaking changes</h3>
 
 * The existing `pennylane.collections.apply` function is no longer accessible
@@ -97,7 +101,7 @@
   [(#1425)](https://github.com/PennyLaneAI/pennylane/pull/1425)
   
 * Fixed a bug in the `torch` interface that prevented gradients from being
-  computed on a GPU [(#1426)](https://github.com/PennyLaneAI/pennylane/pull/1426).
+  computed on a GPU. [(#1426)](https://github.com/PennyLaneAI/pennylane/pull/1426)
 
 * Quantum function transforms now preserve the format of the measurement
   results, so that a single measurement returns a single value rather than
@@ -118,7 +122,7 @@
 
 This release contains contributions from (in alphabetical order):
 
-Olivia Di Matteo, Josh Izaac, Romain Moyard, Ashish Panigrahi.
+Olivia Di Matteo, Josh Izaac, Romain Moyard, Ashish Panigrahi, Maria Schuld.
 
 
 # Release 0.16.0 (current release)
diff --git a/doc/development/adding_templates.rst b/doc/development/adding_templates.rst
index a92168f96..72445dde1 100644
--- a/doc/development/adding_templates.rst
+++ b/doc/development/adding_templates.rst
@@ -92,7 +92,7 @@ and invert the wires that the operation acts on.
         num_wires = AnyWires
         par_domain = "A"  # note: this attribute will be deprecated soon
 
-        def __init__(weights, raw_wires)
+        def __init__(weights, raw_wires, id=None)
 
             shp = qml.math.shape(weights)
             if len(shp) != 1:
@@ -104,8 +104,9 @@ and invert the wires that the operation acts on.
             # pre-process wires
             inverted_wires = wires[::-1]
 
-            # initialise operation with pre-processed parameters and wires
-            super().__init__(new_weights, wires=inverted_wires)
+            # initialise operation with pre-processed parameters and wires,
+            # and possibly with a custom id
+            super().__init__(new_weights, wires=inverted_wires, id=id)
 
 
         def expand(self):
diff --git a/pennylane/templates/embeddings/amplitude.py b/pennylane/templates/embeddings/amplitude.py
index 4a0eeb71b..307b4f55b 100644
--- a/pennylane/templates/embeddings/amplitude.py
+++ b/pennylane/templates/embeddings/amplitude.py
@@ -125,7 +125,9 @@ class AmplitudeEmbedding(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, features, wires, pad_with=None, normalize=False, pad=None, do_queue=True):
+    def __init__(
+        self, features, wires, pad_with=None, normalize=False, pad=None, do_queue=True, id=None
+    ):
 
         # pad is replaced with the more verbose pad_with
         if pad is not None:
@@ -141,7 +143,7 @@ class AmplitudeEmbedding(Operation):
         self.normalize = normalize
 
         features = self._preprocess(features, wires, pad_with, normalize)
-        super().__init__(features, wires=wires, do_queue=do_queue)
+        super().__init__(features, wires=wires, do_queue=do_queue, id=id)
 
     def adjoint(self):  # pylint: disable=arguments-differ
         return qml.adjoint(qml.templates.MottonenStatePreparation)(
diff --git a/pennylane/templates/embeddings/angle.py b/pennylane/templates/embeddings/angle.py
index 7d03f52ce..dd5204384 100644
--- a/pennylane/templates/embeddings/angle.py
+++ b/pennylane/templates/embeddings/angle.py
@@ -50,7 +50,7 @@ class AngleEmbedding(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, features, wires, rotation="X", do_queue=True):
+    def __init__(self, features, wires, rotation="X", do_queue=True, id=None):
 
         if rotation not in ROT:
             raise ValueError(f"Rotation option {rotation} not recognized.")
@@ -66,7 +66,7 @@ class AngleEmbedding(Operation):
             )
 
         wires = wires[:n_features]
-        super().__init__(features, wires=wires, do_queue=do_queue)
+        super().__init__(features, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/embeddings/basis.py b/pennylane/templates/embeddings/basis.py
index 94ea09eac..9f957f539 100644
--- a/pennylane/templates/embeddings/basis.py
+++ b/pennylane/templates/embeddings/basis.py
@@ -41,7 +41,7 @@ class BasisEmbedding(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, features, wires, do_queue=True):
+    def __init__(self, features, wires, do_queue=True, id=None):
 
         wires = Wires(wires)
         shape = qml.math.shape(features)
@@ -58,7 +58,7 @@ class BasisEmbedding(Operation):
         if not set(features).issubset({0, 1}):
             raise ValueError(f"Basis state must only consist of 0s and 1s; got {features}")
 
-        super().__init__(features, wires=wires, do_queue=do_queue)
+        super().__init__(features, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/embeddings/displacement.py b/pennylane/templates/embeddings/displacement.py
index 981699bea..f313a74d3 100644
--- a/pennylane/templates/embeddings/displacement.py
+++ b/pennylane/templates/embeddings/displacement.py
@@ -49,7 +49,7 @@ class DisplacementEmbedding(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, features, wires, method="amplitude", c=0.1, do_queue=True):
+    def __init__(self, features, wires, method="amplitude", c=0.1, do_queue=True, id=None):
 
         shape = qml.math.shape(features)
         constants = [c] * shape[0]
@@ -71,7 +71,7 @@ class DisplacementEmbedding(Operation):
         else:
             raise ValueError(f"did not recognize method {method}")
 
-        super().__init__(pars, wires=wires, do_queue=do_queue)
+        super().__init__(pars, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/embeddings/iqp.py b/pennylane/templates/embeddings/iqp.py
index 5e7e59039..21015951e 100644
--- a/pennylane/templates/embeddings/iqp.py
+++ b/pennylane/templates/embeddings/iqp.py
@@ -167,7 +167,7 @@ class IQPEmbedding(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, features, wires, n_repeats=1, pattern=None, do_queue=True):
+    def __init__(self, features, wires, n_repeats=1, pattern=None, do_queue=True, id=None):
 
         shape = qml.math.shape(features)
 
@@ -185,7 +185,7 @@ class IQPEmbedding(Operation):
         self.pattern = pattern
         self.n_repeats = n_repeats
 
-        super().__init__(features, wires=wires, do_queue=do_queue)
+        super().__init__(features, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/embeddings/qaoa.py b/pennylane/templates/embeddings/qaoa.py
index 376319864..31a62df59 100644
--- a/pennylane/templates/embeddings/qaoa.py
+++ b/pennylane/templates/embeddings/qaoa.py
@@ -201,7 +201,7 @@ class QAOAEmbedding(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, features, weights, wires, local_field="Y", do_queue=True):
+    def __init__(self, features, weights, wires, local_field="Y", do_queue=True, id=None):
 
         if local_field == "Z":
             self.local_field = qml.RZ
@@ -213,7 +213,7 @@ class QAOAEmbedding(Operation):
             raise ValueError(f"did not recognize local field {local_field}")
 
         self._preprocess(features, weights, wires)
-        super().__init__(features, weights, wires=wires, do_queue=do_queue)
+        super().__init__(features, weights, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/embeddings/squeezing.py b/pennylane/templates/embeddings/squeezing.py
index 6fdd3c49a..78a5061f8 100644
--- a/pennylane/templates/embeddings/squeezing.py
+++ b/pennylane/templates/embeddings/squeezing.py
@@ -50,7 +50,7 @@ class SqueezingEmbedding(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, features, wires, method="amplitude", c=0.1, do_queue=True):
+    def __init__(self, features, wires, method="amplitude", c=0.1, do_queue=True, id=None):
 
         shape = qml.math.shape(features)
         constants = [c] * shape[0]
@@ -72,7 +72,7 @@ class SqueezingEmbedding(Operation):
         else:
             raise ValueError(f"did not recognize method {method}")
 
-        super().__init__(pars, wires=wires, do_queue=do_queue)
+        super().__init__(pars, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/layers/basic_entangler.py b/pennylane/templates/layers/basic_entangler.py
index 78e55d8c6..6440b7f2c 100644
--- a/pennylane/templates/layers/basic_entangler.py
+++ b/pennylane/templates/layers/basic_entangler.py
@@ -14,7 +14,7 @@
 r"""
 Contains the BasicEntanglerLayers template.
 """
-# pylint: disable=consider-using-enumerate
+# pylint: disable=consider-using-enumerate,too-many-arguments
 import pennylane as qml
 from pennylane.operation import Operation, AnyWires
 
@@ -125,7 +125,7 @@ class BasicEntanglerLayers(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, weights, wires=None, rotation=None, do_queue=True):
+    def __init__(self, weights, wires=None, rotation=None, do_queue=True, id=None):
 
         self.rotation = rotation or qml.RX
 
@@ -137,7 +137,7 @@ class BasicEntanglerLayers(Operation):
                 f"Weights tensor must have second dimension of length {len(wires)}; got {shape[1]}"
             )
 
-        super().__init__(weights, wires=wires, do_queue=do_queue)
+        super().__init__(weights, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/layers/cv_neural_net.py b/pennylane/templates/layers/cv_neural_net.py
index c17404da2..cfb067a47 100644
--- a/pennylane/templates/layers/cv_neural_net.py
+++ b/pennylane/templates/layers/cv_neural_net.py
@@ -99,6 +99,7 @@ class CVNeuralNetLayers(Operation):
         k,
         wires,
         do_queue=True,
+        id=None,
     ):
 
         n_wires = len(wires)
@@ -135,6 +136,7 @@ class CVNeuralNetLayers(Operation):
             k,
             wires=wires,
             do_queue=do_queue,
+            id=id,
         )
 
     def expand(self):
diff --git a/pennylane/templates/layers/particle_conserving_u1.py b/pennylane/templates/layers/particle_conserving_u1.py
index 097f1bfd5..087ac5e8f 100644
--- a/pennylane/templates/layers/particle_conserving_u1.py
+++ b/pennylane/templates/layers/particle_conserving_u1.py
@@ -229,7 +229,7 @@ class ParticleConservingU1(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, weights, wires, init_state=None, do_queue=True):
+    def __init__(self, weights, wires, init_state=None, do_queue=True, id=None):
 
         if len(wires) < 2:
             raise ValueError(
@@ -257,7 +257,7 @@ class ParticleConservingU1(Operation):
         # since init_state can never be differentiable
         self.init_state = qml.math.toarray(init_state)
 
-        super().__init__(weights, wires=wires, do_queue=do_queue)
+        super().__init__(weights, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/layers/particle_conserving_u2.py b/pennylane/templates/layers/particle_conserving_u2.py
index e0ac00a8a..dbf959760 100644
--- a/pennylane/templates/layers/particle_conserving_u2.py
+++ b/pennylane/templates/layers/particle_conserving_u2.py
@@ -151,7 +151,7 @@ class ParticleConservingU2(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, weights, wires, init_state=None, do_queue=True):
+    def __init__(self, weights, wires, init_state=None, do_queue=True, id=None):
 
         if len(wires) < 2:
             raise ValueError(
@@ -174,7 +174,7 @@ class ParticleConservingU2(Operation):
         # since init_state can never be differentiable
         self.init_state = qml.math.toarray(init_state)
 
-        super().__init__(weights, wires=wires, do_queue=do_queue)
+        super().__init__(weights, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/layers/random.py b/pennylane/templates/layers/random.py
index 5a700260b..4d0da0dbd 100644
--- a/pennylane/templates/layers/random.py
+++ b/pennylane/templates/layers/random.py
@@ -188,6 +188,7 @@ class RandomLayers(Operation):
         rotations=None,
         seed=42,
         do_queue=True,
+        id=None,
     ):
 
         self.seed = seed
@@ -201,7 +202,7 @@ class RandomLayers(Operation):
         self.imprimitive = imprimitive or qml.CNOT
         self.ratio_imprimitive = ratio_imprim
 
-        super().__init__(weights, wires=wires, do_queue=do_queue)
+        super().__init__(weights, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/layers/simplified_two_design.py b/pennylane/templates/layers/simplified_two_design.py
index cddb6facd..8ca767b22 100644
--- a/pennylane/templates/layers/simplified_two_design.py
+++ b/pennylane/templates/layers/simplified_two_design.py
@@ -102,7 +102,7 @@ class SimplifiedTwoDesign(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, initial_layer_weights, weights, wires, do_queue=True):
+    def __init__(self, initial_layer_weights, weights, wires, do_queue=True, id=None):
 
         shape = qml.math.shape(weights)
 
@@ -125,7 +125,7 @@ class SimplifiedTwoDesign(Operation):
 
         self.n_layers = shape[0]
 
-        super().__init__(initial_layer_weights, weights, wires=wires, do_queue=do_queue)
+        super().__init__(initial_layer_weights, weights, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/layers/strongly_entangling.py b/pennylane/templates/layers/strongly_entangling.py
index b1f526ec1..699f3f9d2 100644
--- a/pennylane/templates/layers/strongly_entangling.py
+++ b/pennylane/templates/layers/strongly_entangling.py
@@ -68,7 +68,7 @@ class StronglyEntanglingLayers(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, weights, wires, ranges=None, imprimitive=None, do_queue=True):
+    def __init__(self, weights, wires, ranges=None, imprimitive=None, do_queue=True, id=None):
 
         shape = qml.math.shape(weights)
         self.n_layers = shape[0]
@@ -106,7 +106,7 @@ class StronglyEntanglingLayers(Operation):
 
         self.imprimitive = imprimitive or qml.CNOT
 
-        super().__init__(weights, wires=wires, do_queue=do_queue)
+        super().__init__(weights, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/state_preparations/arbitrary_state_preparation.py b/pennylane/templates/state_preparations/arbitrary_state_preparation.py
index aa23dc3b2..1c0222eea 100644
--- a/pennylane/templates/state_preparations/arbitrary_state_preparation.py
+++ b/pennylane/templates/state_preparations/arbitrary_state_preparation.py
@@ -83,7 +83,7 @@ class ArbitraryStatePreparation(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, weights, wires, do_queue=True):
+    def __init__(self, weights, wires, do_queue=True, id=None):
 
         shape = qml.math.shape(weights)
         if shape != (2 ** (len(wires) + 1) - 2,):
@@ -91,7 +91,7 @@ class ArbitraryStatePreparation(Operation):
                 f"Weights tensor must be of shape {(2 ** (len(wires) + 1) - 2,)}; got {shape}."
             )
 
-        super().__init__(weights, wires=wires, do_queue=do_queue)
+        super().__init__(weights, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/state_preparations/basis.py b/pennylane/templates/state_preparations/basis.py
index 5b326e938..ba4426a0a 100644
--- a/pennylane/templates/state_preparations/basis.py
+++ b/pennylane/templates/state_preparations/basis.py
@@ -52,7 +52,7 @@ class BasisStatePreparation(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, basis_state, wires, do_queue=True):
+    def __init__(self, basis_state, wires, do_queue=True, id=None):
 
         shape = qml.math.shape(basis_state)
 
@@ -69,7 +69,7 @@ class BasisStatePreparation(Operation):
         if not all(bit in [0, 1] for bit in basis_state):
             raise ValueError(f"Basis state must only consist of 0s and 1s; got {basis_state}")
 
-        super().__init__(basis_state, wires=wires, do_queue=do_queue)
+        super().__init__(basis_state, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/state_preparations/mottonen.py b/pennylane/templates/state_preparations/mottonen.py
index fe3ca856a..cb3c13389 100644
--- a/pennylane/templates/state_preparations/mottonen.py
+++ b/pennylane/templates/state_preparations/mottonen.py
@@ -249,7 +249,7 @@ class MottonenStatePreparation(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, state_vector, wires, do_queue=True):
+    def __init__(self, state_vector, wires, do_queue=True, id=None):
 
         shape = qml.math.shape(state_vector)
 
@@ -266,7 +266,7 @@ class MottonenStatePreparation(Operation):
         if not qml.math.allclose(norm, 1.0, atol=1e-3):
             raise ValueError("State vector has to be of norm 1.0, got {}".format(norm))
 
-        super().__init__(state_vector, wires=wires, do_queue=do_queue)
+        super().__init__(state_vector, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/subroutines/all_singles_doubles.py b/pennylane/templates/subroutines/all_singles_doubles.py
index 2d501258e..35f8173f0 100644
--- a/pennylane/templates/subroutines/all_singles_doubles.py
+++ b/pennylane/templates/subroutines/all_singles_doubles.py
@@ -115,7 +115,9 @@ class AllSinglesDoubles(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, weights, wires, hf_state, singles=None, doubles=None, do_queue=True):
+    def __init__(
+        self, weights, wires, hf_state, singles=None, doubles=None, do_queue=True, id=None
+    ):
 
         if len(wires) < 2:
             raise ValueError(
@@ -155,7 +157,7 @@ class AllSinglesDoubles(Operation):
         if hf_state.dtype != np.dtype("int"):
             raise ValueError(f"Elements of 'hf_state' must be integers; got {hf_state.dtype}")
 
-        super().__init__(weights, wires=wires, do_queue=do_queue)
+        super().__init__(weights, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/subroutines/approx_time_evolution.py b/pennylane/templates/subroutines/approx_time_evolution.py
index 0bc5e2e8d..8e5bef420 100644
--- a/pennylane/templates/subroutines/approx_time_evolution.py
+++ b/pennylane/templates/subroutines/approx_time_evolution.py
@@ -101,7 +101,7 @@ class ApproxTimeEvolution(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, hamiltonian, time, n, do_queue=True):
+    def __init__(self, hamiltonian, time, n, do_queue=True, id=None):
 
         if not isinstance(hamiltonian, qml.vqe.vqe.Hamiltonian):
             raise ValueError(
@@ -114,7 +114,7 @@ class ApproxTimeEvolution(Operation):
         wire_list = [term.wires for term in hamiltonian.ops]
         unique_wires = list(set(wire_list))
 
-        super().__init__(hamiltonian, time, n, wires=unique_wires, do_queue=do_queue)
+        super().__init__(hamiltonian, time, n, wires=unique_wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/subroutines/arbitrary_unitary.py b/pennylane/templates/subroutines/arbitrary_unitary.py
index 835ae3470..e6acb4fde 100644
--- a/pennylane/templates/subroutines/arbitrary_unitary.py
+++ b/pennylane/templates/subroutines/arbitrary_unitary.py
@@ -96,7 +96,7 @@ class ArbitraryUnitary(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, weights, wires, do_queue=True):
+    def __init__(self, weights, wires, do_queue=True, id=None):
 
         shape = qml.math.shape(weights)
         if shape != (4 ** len(wires) - 1,):
@@ -104,7 +104,7 @@ class ArbitraryUnitary(Operation):
                 f"Weights tensor must be of shape {(4 ** len(wires) - 1,)}; got {shape}."
             )
 
-        super().__init__(weights, wires=wires, do_queue=do_queue)
+        super().__init__(weights, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/subroutines/double_excitation_unitary.py b/pennylane/templates/subroutines/double_excitation_unitary.py
index a35fe29a2..ba0fa88bd 100644
--- a/pennylane/templates/subroutines/double_excitation_unitary.py
+++ b/pennylane/templates/subroutines/double_excitation_unitary.py
@@ -477,7 +477,7 @@ class DoubleExcitationUnitary(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, weight, wires1=None, wires2=None, do_queue=True):
+    def __init__(self, weight, wires1=None, wires2=None, do_queue=True, id=None):
 
         if len(wires1) < 2:
             raise ValueError(
@@ -498,7 +498,7 @@ class DoubleExcitationUnitary(Operation):
         self.wires2 = list(wires2)
         wires = wires1 + wires2
 
-        super().__init__(weight, wires=wires, do_queue=do_queue)
+        super().__init__(weight, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/subroutines/permute.py b/pennylane/templates/subroutines/permute.py
index 1666c0228..c9f05448a 100644
--- a/pennylane/templates/subroutines/permute.py
+++ b/pennylane/templates/subroutines/permute.py
@@ -144,7 +144,7 @@ class Permute(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, permutation, wires, do_queue=True):
+    def __init__(self, permutation, wires, do_queue=True, id=None):
 
         if len(permutation) <= 1 or len(wires) <= 1:
             raise ValueError("Permutations must involve at least 2 qubits.")
@@ -162,7 +162,7 @@ class Permute(Operation):
             if label not in wires:
                 raise ValueError(f"Cannot permute wire {label} not present in wire set.")
 
-        super().__init__(permutation, wires=wires, do_queue=do_queue)
+        super().__init__(permutation, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/subroutines/qmc.py b/pennylane/templates/subroutines/qmc.py
index e4d46ca06..09e362bf3 100644
--- a/pennylane/templates/subroutines/qmc.py
+++ b/pennylane/templates/subroutines/qmc.py
@@ -14,6 +14,7 @@
 """
 Contains the QuantumMonteCarlo template and utility functions.
 """
+# pylint: disable=too-many-arguments
 import numpy as np
 import pennylane as qml
 from pennylane.operation import AnyWires, Operation
@@ -330,7 +331,7 @@ class QuantumMonteCarlo(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, probs, func, target_wires, estimation_wires, do_queue=True):
+    def __init__(self, probs, func, target_wires, estimation_wires, do_queue=True, id=None):
         if isinstance(probs, np.ndarray) and probs.ndim != 1:
             raise ValueError("The probability distribution must be specified as a flat array")
 
@@ -356,7 +357,7 @@ class QuantumMonteCarlo(Operation):
         A = probs_to_unitary(probs)
         R = func_to_unitary(func, dim_p)
         Q = make_Q(A, R)
-        super().__init__(A, R, Q, wires=wires, do_queue=do_queue)
+        super().__init__(A, R, Q, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
         A, R, Q = self.parameters
diff --git a/pennylane/templates/subroutines/qpe.py b/pennylane/templates/subroutines/qpe.py
index 0391e1513..405edab39 100644
--- a/pennylane/templates/subroutines/qpe.py
+++ b/pennylane/templates/subroutines/qpe.py
@@ -14,6 +14,7 @@
 """
 Contains the QuantumPhaseEstimation template.
 """
+# pylint: disable=too-many-arguments
 import pennylane as qml
 from pennylane.operation import AnyWires, Operation
 from pennylane.ops import Hadamard, ControlledQubitUnitary, QFT
@@ -107,7 +108,7 @@ class QuantumPhaseEstimation(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, unitary, target_wires, estimation_wires, do_queue=True):
+    def __init__(self, unitary, target_wires, estimation_wires, do_queue=True, id=None):
         self.target_wires = list(target_wires)
         self.estimation_wires = list(estimation_wires)
 
@@ -118,7 +119,7 @@ class QuantumPhaseEstimation(Operation):
                 "The target wires and estimation wires must be different"
             )
 
-        super().__init__(unitary, wires=wires, do_queue=do_queue)
+        super().__init__(unitary, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
         unitary = self.parameters[0]
diff --git a/pennylane/templates/subroutines/single_excitation_unitary.py b/pennylane/templates/subroutines/single_excitation_unitary.py
index f02e2c8a7..8b6a8c2ae 100644
--- a/pennylane/templates/subroutines/single_excitation_unitary.py
+++ b/pennylane/templates/subroutines/single_excitation_unitary.py
@@ -116,7 +116,7 @@ class SingleExcitationUnitary(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, weight, wires=None, do_queue=True):
+    def __init__(self, weight, wires=None, do_queue=True, id=None):
         if len(wires) < 2:
             raise ValueError("expected at least two wires; got {}".format(len(wires)))
 
@@ -124,7 +124,7 @@ class SingleExcitationUnitary(Operation):
         if shape != ():
             raise ValueError(f"Weight must be a scalar tensor {()}; got shape {shape}.")
 
-        super().__init__(weight, wires=wires, do_queue=do_queue)
+        super().__init__(weight, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 
diff --git a/pennylane/templates/subroutines/uccsd.py b/pennylane/templates/subroutines/uccsd.py
index e21bc13cc..b6dc04b4f 100644
--- a/pennylane/templates/subroutines/uccsd.py
+++ b/pennylane/templates/subroutines/uccsd.py
@@ -144,7 +144,9 @@ class UCCSD(Operation):
     num_wires = AnyWires
     par_domain = "A"
 
-    def __init__(self, weights, wires, s_wires=None, d_wires=None, init_state=None, do_queue=True):
+    def __init__(
+        self, weights, wires, s_wires=None, d_wires=None, init_state=None, do_queue=True, id=None
+    ):
 
         if (not s_wires) and (not d_wires):
             raise ValueError(
@@ -178,7 +180,7 @@ class UCCSD(Operation):
 
         self.init_state_flipped = np.flip(init_state)
 
-        super().__init__(weights, wires=wires, do_queue=do_queue)
+        super().__init__(weights, wires=wires, do_queue=do_queue, id=id)
 
     def expand(self):
 


Test patch:
diff --git a/tests/templates/test_embeddings/test_amplitude.py b/tests/templates/test_embeddings/test_amplitude.py
index 1b53a3650..12c04f745 100644
--- a/tests/templates/test_embeddings/test_amplitude.py
+++ b/tests/templates/test_embeddings/test_amplitude.py
@@ -244,6 +244,11 @@ class TestInputs:
         ):
             circuit(x=inputs)
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.AmplitudeEmbedding(np.array([1, 0]), wires=[0], id="a")
+        assert template.id == "a"
+
 
 def circuit_template(features):
     qml.templates.AmplitudeEmbedding(features, wires=range(3))
diff --git a/tests/templates/test_embeddings/test_angle.py b/tests/templates/test_embeddings/test_angle.py
index 41554077f..ff750080a 100644
--- a/tests/templates/test_embeddings/test_angle.py
+++ b/tests/templates/test_embeddings/test_angle.py
@@ -148,6 +148,11 @@ class TestInputs:
         with pytest.raises(ValueError, match="Features must be a one-dimensional"):
             circuit(x=[[1], [0]])
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.AngleEmbedding(np.array([1, 2]), wires=[0, 1], id="a")
+        assert template.id == "a"
+
 
 def circuit_template(features):
     qml.templates.AngleEmbedding(features, range(3))
diff --git a/tests/templates/test_embeddings/test_basis.py b/tests/templates/test_embeddings/test_basis.py
index 54c6e0bde..c3179199f 100644
--- a/tests/templates/test_embeddings/test_basis.py
+++ b/tests/templates/test_embeddings/test_basis.py
@@ -116,6 +116,11 @@ class TestInputs:
         with pytest.raises(ValueError, match="Features must be one-dimensional"):
             circuit(x=[[1], [0]])
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.BasisEmbedding([0, 1], wires=[0, 1], id="a")
+        assert template.id == "a"
+
 
 def circuit_template(features):
     qml.templates.BasisEmbedding(features, wires=range(3))
diff --git a/tests/templates/test_embeddings/test_displacement_emb.py b/tests/templates/test_embeddings/test_displacement_emb.py
index 40027fb71..6abbe34d9 100644
--- a/tests/templates/test_embeddings/test_displacement_emb.py
+++ b/tests/templates/test_embeddings/test_displacement_emb.py
@@ -148,6 +148,11 @@ class TestInputs:
         with pytest.raises(ValueError, match="Features must be a one-dimensional"):
             circuit(x=[[1], [0]])
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.DisplacementEmbedding(np.array([1, 2]), wires=[0, 1], id="a")
+        assert template.id == "a"
+
 
 def circuit_template(features):
     qml.templates.DisplacementEmbedding(features, range(3))
diff --git a/tests/templates/test_embeddings/test_iqp_emb.py b/tests/templates/test_embeddings/test_iqp_emb.py
index 5e95e5040..eb46f6bbc 100644
--- a/tests/templates/test_embeddings/test_iqp_emb.py
+++ b/tests/templates/test_embeddings/test_iqp_emb.py
@@ -128,6 +128,11 @@ class TestInputs:
         with pytest.raises(ValueError, match="Features must be"):
             circuit(f=features)
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.IQPEmbedding(np.array([1, 2]), wires=[0, 1], id="a")
+        assert template.id == "a"
+
 
 def circuit_template(features):
     qml.templates.IQPEmbedding(features, range(2))
diff --git a/tests/templates/test_embeddings/test_qaoa_emb.py b/tests/templates/test_embeddings/test_qaoa_emb.py
index 381a4532f..c4e279d09 100644
--- a/tests/templates/test_embeddings/test_qaoa_emb.py
+++ b/tests/templates/test_embeddings/test_qaoa_emb.py
@@ -240,6 +240,13 @@ class TestInputs:
         shape = qml.templates.QAOAEmbedding.shape(n_layers, n_wires)
         assert shape == expected_shape
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.QAOAEmbedding(
+            np.array([0]), weights=np.array([[0]]), wires=[0], id="a"
+        )
+        assert template.id == "a"
+
 
 def circuit_template(features, weights):
     qml.templates.QAOAEmbedding(features, weights, range(2))
diff --git a/tests/templates/test_embeddings/test_squeezing_emb.py b/tests/templates/test_embeddings/test_squeezing_emb.py
index a080cc100..6a072ee3d 100644
--- a/tests/templates/test_embeddings/test_squeezing_emb.py
+++ b/tests/templates/test_embeddings/test_squeezing_emb.py
@@ -146,6 +146,11 @@ class TestInputs:
         with pytest.raises(ValueError, match="Features must be a one-dimensional"):
             circuit(x=[[1], [0]])
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.SqueezingEmbedding(np.array([1, 2]), wires=[0, 1], id="a")
+        assert template.id == "a"
+
 
 def circuit_template(features):
     qml.templates.SqueezingEmbedding(features, range(3))
diff --git a/tests/templates/test_layers/test_basic_entangler.py b/tests/templates/test_layers/test_basic_entangler.py
index 57f719177..b6da4fd83 100644
--- a/tests/templates/test_layers/test_basic_entangler.py
+++ b/tests/templates/test_layers/test_basic_entangler.py
@@ -124,6 +124,11 @@ class TestInputs:
         with pytest.raises(ValueError, match="Weights tensor must have second dimension of length"):
             circuit([[1, 0], [1, 0]])
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.BasicEntanglerLayers(np.array([[1]]), wires=[0], id="a")
+        assert template.id == "a"
+
 
 class TestAttributes:
     """Tests additional methods and attributes"""
diff --git a/tests/templates/test_layers/test_cv_neural_net.py b/tests/templates/test_layers/test_cv_neural_net.py
index a6f643578..9eeaee648 100644
--- a/tests/templates/test_layers/test_cv_neural_net.py
+++ b/tests/templates/test_layers/test_cv_neural_net.py
@@ -139,6 +139,14 @@ class TestInputs:
         with pytest.raises(ValueError, match="Got unexpected shape for one or more parameters"):
             circuit()
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        shapes = expected_shapes(1, 2)
+        weights = [np.random.random(shape) for shape in shapes]
+
+        template = qml.templates.CVNeuralNetLayers(*weights, wires=range(2), id="a")
+        assert template.id == "a"
+
 
 class TestAttributes:
     """Test methods and attributes."""
diff --git a/tests/templates/test_layers/test_particle_conserving_u1.py b/tests/templates/test_layers/test_particle_conserving_u1.py
index d65936b18..37bfbdc06 100644
--- a/tests/templates/test_layers/test_particle_conserving_u1.py
+++ b/tests/templates/test_layers/test_particle_conserving_u1.py
@@ -245,6 +245,13 @@ class TestInputs:
         with pytest.raises(ValueError, match=msg_match):
             circuit()
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.ParticleConservingU1(
+            weights=np.array([[[0.2, -0.6]]]), wires=range(2), init_state=np.array([1, 1]), id="a"
+        )
+        assert template.id == "a"
+
 
 class TestAttributes:
     """Tests additional methods and attributes"""
diff --git a/tests/templates/test_layers/test_particle_conserving_u2.py b/tests/templates/test_layers/test_particle_conserving_u2.py
index 3a05f8e2d..d86350838 100644
--- a/tests/templates/test_layers/test_particle_conserving_u2.py
+++ b/tests/templates/test_layers/test_particle_conserving_u2.py
@@ -196,6 +196,14 @@ class TestInputs:
         with pytest.raises(ValueError, match=msg_match):
             circuit()
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        init_state = np.array([1, 1, 0])
+        template = qml.templates.ParticleConservingU2(
+            weights=np.random.random(size=(1, 5)), wires=range(3), init_state=init_state, id="a"
+        )
+        assert template.id == "a"
+
 
 class TestAttributes:
     """Tests additional methods and attributes"""
diff --git a/tests/templates/test_layers/test_random.py b/tests/templates/test_layers/test_random.py
index 01b3f9a69..3050c906d 100644
--- a/tests/templates/test_layers/test_random.py
+++ b/tests/templates/test_layers/test_random.py
@@ -119,6 +119,11 @@ class TestInputs:
         with pytest.raises(ValueError, match="Weights tensor must be 2-dimensional"):
             circuit(phi)
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.RandomLayers(np.random.random(size=(1, 3)), wires=range(3), id="a")
+        assert template.id == "a"
+
 
 class TestAttributes:
     """Tests additional methods and attributes"""
diff --git a/tests/templates/test_layers/test_simplified_twodesign.py b/tests/templates/test_layers/test_simplified_twodesign.py
index 91cd5af43..0b36743e9 100644
--- a/tests/templates/test_layers/test_simplified_twodesign.py
+++ b/tests/templates/test_layers/test_simplified_twodesign.py
@@ -161,6 +161,13 @@ class TestInputs:
             weights = np.random.randn(2, 1, 2)
             circuit(initial_layer, weights)
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        weights = np.random.random(size=(1, 2, 2))
+        initial_layer = np.random.randn(3)
+        template = qml.templates.SimplifiedTwoDesign(initial_layer, weights, wires=range(3), id="a")
+        assert template.id == "a"
+
 
 class TestAttributes:
     """Tests additional methods and attributes"""
diff --git a/tests/templates/test_layers/test_strongly_entangling.py b/tests/templates/test_layers/test_strongly_entangling.py
index d72f3fe53..6bb11b44d 100644
--- a/tests/templates/test_layers/test_strongly_entangling.py
+++ b/tests/templates/test_layers/test_strongly_entangling.py
@@ -160,6 +160,13 @@ class TestInputs:
             weights = np.random.randn(1, 2, 3)
             circuit(weights, ranges=[0])
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.StronglyEntanglingLayers(
+            np.array([[[1, 2, 3]]]), wires=[0], id="a"
+        )
+        assert template.id == "a"
+
 
 class TestAttributes:
     """Tests additional methods and attributes"""
diff --git a/tests/templates/test_state_preparations/test_arbitrary_state_prep.py b/tests/templates/test_state_preparations/test_arbitrary_state_prep.py
index 3baffbc96..d1fb92480 100644
--- a/tests/templates/test_state_preparations/test_arbitrary_state_prep.py
+++ b/tests/templates/test_state_preparations/test_arbitrary_state_prep.py
@@ -192,6 +192,13 @@ class TestInputs:
             weights = np.zeros(12)
             circuit(weights)
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.ArbitraryStatePreparation(
+            np.random.random(size=(2 ** 4 - 2)), wires=[0, 1, 2], id="a"
+        )
+        assert template.id == "a"
+
 
 class TestAttributes:
     """Tests additional methods and attributes"""
diff --git a/tests/templates/test_state_preparations/test_basis_state_prep.py b/tests/templates/test_state_preparations/test_basis_state_prep.py
index 75842f55f..51ae28f8f 100644
--- a/tests/templates/test_state_preparations/test_basis_state_prep.py
+++ b/tests/templates/test_state_preparations/test_basis_state_prep.py
@@ -149,3 +149,8 @@ class TestInputs:
         with pytest.raises(ValueError, match="Basis state must only consist of"):
             basis_state = np.array([0, 2])
             circuit(basis_state)
+
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.BasisStatePreparation(np.array([0, 1]), wires=[0, 1], id="a")
+        assert template.id == "a"
diff --git a/tests/templates/test_state_preparations/test_mottonen_state_prep.py b/tests/templates/test_state_preparations/test_mottonen_state_prep.py
index 9958585e2..22e93ad5f 100644
--- a/tests/templates/test_state_preparations/test_mottonen_state_prep.py
+++ b/tests/templates/test_state_preparations/test_mottonen_state_prep.py
@@ -17,7 +17,6 @@ Unit tests for the ArbitraryStatePreparation template.
 import pytest
 import numpy as np
 import pennylane as qml
-from pennylane import numpy as pnp
 
 torch = pytest.importorskip("torch", minversion="1.3")
 from pennylane.templates.state_preparations.mottonen import gray_code, _get_alpha_y
@@ -322,6 +321,11 @@ class TestInputs:
         with pytest.raises(ValueError, match="State vector must be a one-dimensional"):
             qml.templates.MottonenStatePreparation(state_vector, 2)
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.MottonenStatePreparation(np.array([0, 1]), wires=[0], id="a")
+        assert template.id == "a"
+
 
 class TestGradient:
     """Tests gradients."""
diff --git a/tests/templates/test_subroutines/test_all_singles_doubles.py b/tests/templates/test_subroutines/test_all_singles_doubles.py
index 7ec1029c3..2433d5fe6 100644
--- a/tests/templates/test_subroutines/test_all_singles_doubles.py
+++ b/tests/templates/test_subroutines/test_all_singles_doubles.py
@@ -275,6 +275,18 @@ class TestInputs:
                 doubles=doubles,
             )
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.AllSinglesDoubles(
+            [1, 2],
+            wires=range(4),
+            hf_state=np.array([1, 1, 0, 0]),
+            singles=[[0, 1]],
+            doubles=[[0, 1, 2, 3]],
+            id="a",
+        )
+        assert template.id == "a"
+
 
 class TestAttributes:
     """Tests additional methods and attributes"""
diff --git a/tests/templates/test_subroutines/test_approx_time_evolution.py b/tests/templates/test_subroutines/test_approx_time_evolution.py
index ff1b831ef..3b7e39d98 100644
--- a/tests/templates/test_subroutines/test_approx_time_evolution.py
+++ b/tests/templates/test_subroutines/test_approx_time_evolution.py
@@ -204,6 +204,12 @@ class TestInputs:
         ):
             circuit()
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        h = qml.Hamiltonian([1, 1], [qml.PauliX(0), qml.PauliY(0)])
+        template = qml.templates.ApproxTimeEvolution(h, 2, 3, id="a")
+        assert template.id == "a"
+
 
 # test data for gradient tests
 
diff --git a/tests/templates/test_subroutines/test_arbitrary_unitary.py b/tests/templates/test_subroutines/test_arbitrary_unitary.py
index 2bae1ffb3..40c860e2d 100644
--- a/tests/templates/test_subroutines/test_arbitrary_unitary.py
+++ b/tests/templates/test_subroutines/test_arbitrary_unitary.py
@@ -187,6 +187,13 @@ class TestInputs:
             weights = np.array([0, 1])
             circuit(weights)
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.ArbitraryUnitary(
+            np.random.random(size=(63,)), wires=range(3), id="a"
+        )
+        assert template.id == "a"
+
 
 class TestAttributes:
     """Tests class attributes and methods."""
diff --git a/tests/templates/test_subroutines/test_double_excitation.py b/tests/templates/test_subroutines/test_double_excitation.py
index b01bafff8..bd06ac074 100644
--- a/tests/templates/test_subroutines/test_double_excitation.py
+++ b/tests/templates/test_subroutines/test_double_excitation.py
@@ -260,6 +260,13 @@ class TestInputs:
         with pytest.raises(ValueError, match=msg_match):
             qnode(weight)
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.DoubleExcitationUnitary(
+            0.4, wires1=[0, 2], wires2=[1, 4, 3], id="a"
+        )
+        assert template.id == "a"
+
 
 def circuit_template(weight):
     qml.templates.DoubleExcitationUnitary(weight, wires1=[0, 1], wires2=[2, 3])
diff --git a/tests/templates/test_subroutines/test_permute.py b/tests/templates/test_subroutines/test_permute.py
index 32285175a..bd0e65620 100644
--- a/tests/templates/test_subroutines/test_permute.py
+++ b/tests/templates/test_subroutines/test_permute.py
@@ -334,3 +334,8 @@ class TestInputs:
         with qml.tape.QuantumTape() as tape:
             with pytest.raises(ValueError, match=expected_error_message):
                 qml.templates.Permute(permutation_order, wires=wire_labels)
+
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.Permute([0, 1, 2], wires=[0, 1, 2], id="a")
+        assert template.id == "a"
diff --git a/tests/templates/test_subroutines/test_qmc.py b/tests/templates/test_subroutines/test_qmc.py
index 118782987..242060100 100644
--- a/tests/templates/test_subroutines/test_qmc.py
+++ b/tests/templates/test_subroutines/test_qmc.py
@@ -356,3 +356,19 @@ class TestQuantumMonteCarlo:
 
         exact = 0.432332358381693654
         assert np.allclose(mu_estimated, exact, rtol=1e-3)
+
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        xs = np.linspace(-np.pi, np.pi, 2 ** 5)
+        probs = np.array([norm().pdf(x) for x in xs])
+        probs /= np.sum(probs)
+        func = lambda i: np.cos(xs[i]) ** 2
+
+        target_wires = [0, "a", -1.1, -10, "bbb", 1000]
+        estimation_wires = ["bob", -3, 42, "penny", "lane", 247, "straw", "berry", 5.5, 6.6]
+
+        template = qml.templates.QuantumMonteCarlo(
+            probs, func, target_wires=target_wires, estimation_wires=estimation_wires, id="a"
+        )
+
+        assert template.id == "a"
diff --git a/tests/templates/test_subroutines/test_qpe.py b/tests/templates/test_subroutines/test_qpe.py
index 7b7043a7c..8c9938eab 100644
--- a/tests/templates/test_subroutines/test_qpe.py
+++ b/tests/templates/test_subroutines/test_qpe.py
@@ -141,3 +141,10 @@ class TestInputs:
             qml.templates.QuantumPhaseEstimation(
                 np.eye(2), target_wires=[0, 1], estimation_wires=[1, 2]
             )
+
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.QuantumPhaseEstimation(
+            np.eye(2), target_wires=[0, 1], estimation_wires=[2, 3], id="a"
+        )
+        assert template.id == "a"
diff --git a/tests/templates/test_subroutines/test_single_excitation.py b/tests/templates/test_subroutines/test_single_excitation.py
index 85eed996d..ff3307b4e 100644
--- a/tests/templates/test_subroutines/test_single_excitation.py
+++ b/tests/templates/test_subroutines/test_single_excitation.py
@@ -155,6 +155,11 @@ class TestInputs:
         with pytest.raises(ValueError, match=msg_match):
             qnode(weight=weight)
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.SingleExcitationUnitary(0.4, wires=[1, 0, 2], id="a")
+        assert template.id == "a"
+
 
 def circuit_template(weight):
     qml.templates.SingleExcitationUnitary(weight, wires=[0, 1])
diff --git a/tests/templates/test_subroutines/test_ucssd.py b/tests/templates/test_subroutines/test_ucssd.py
index fa137d90d..896941706 100644
--- a/tests/templates/test_subroutines/test_ucssd.py
+++ b/tests/templates/test_subroutines/test_ucssd.py
@@ -269,6 +269,18 @@ class TestInputs:
                 init_state=init_state,
             )
 
+    def test_id(self):
+        """Tests that the id attribute can be set."""
+        template = qml.templates.UCCSD(
+            [0.1, 0.2],
+            wires=range(4),
+            s_wires=[[0, 1]],
+            d_wires=[[[0, 1], [2, 3]]],
+            init_state=np.array([0, 1, 0, 1]),
+            id="a",
+        )
+        assert template.id == "a"
+
 
 def circuit_template(weights):
     qml.templates.UCCSD(