We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[BUG] `qml.specs`: `max_expansion` keyword argument is not doing anything (what should it do?)
### Expected behavior

I'm not sure what `max_expansion` should be doing. Currently, it looks like it isn't doing anything. Maybe just the docstring

> - max_expansion (int) – The number of times the internal circuit should be expanded when calculating the specification. Defaults to qnode.max_expansion.

can be clarified?

### Actual behavior

Consider this circuit:

```
@qml.qnode(dev)
def circuit():
    qml.templates.StronglyEntanglingLayers(
        np.random.random((3, 2, 3)),
        wires=range(2)
    )
    return qml.probs(wires=(0,1))
```

Then, 

```
print(qml.specs(circuit)() == qml.specs(circuit, max_expansion=7)()) # output: True
```

no matter what the value `max_expansion` is assigned to.



### Additional information

Specifying `expansion_strategy = "device"` below updates the `'depth'` key:

```
@qml.qnode(dev, expansion_strategy="device")
def circuit():
    qml.templates.StronglyEntanglingLayers(
        np.random.random((3, 2, 3)),
        wires=range(2)
    )
    return qml.probs(wires=(0,1))

print(qml.specs(circuit)()) # 'depth' key is changed from 1 (without expansion_strategy) to 9
```

### Source code

```shell
import pennylane as qml
from pennylane import numpy as np

dev = qml.device('default.qubit', wires=2)

def layer():
    qml.templates.StronglyEntanglingLayers(
        np.random.random((3, 2, 3)),
        wires=range(2)
    )

@qml.qnode(dev, expansion_strategy="device")
def circuit_exp_strat():
    layer()
    return qml.probs(wires=(0,1))

@qml.qnode(dev)
def circuit():
    layer()
    return qml.probs(wires=(0,1))

print(qml.specs(circuit_exp_strat)())
print(qml.specs(circuit)())
print(qml.specs(circuit, max_expansion = 7)())
```


### Tracebacks

```shell
N/A
```


### System information

```shell
Name: PennyLane
Version: 0.22.1
Summary: PennyLane is a Python quantum machine learning library by Xanadu Inc.
Home-page: https://github.com/XanaduAI/pennylane
Author: 
Author-email: 
License: Apache License 2.0
Location: /opt/anaconda3/lib/python3.9/site-packages
Requires: toml, appdirs, retworkx, pennylane-lightning, numpy, autograd, semantic-version, networkx, scipy, autoray, cachetools
Required-by: PennyLane-Lightning
Platform info:           macOS-10.16-x86_64-i386-64bit
Python version:          3.9.7
Numpy version:           1.20.3
Scipy version:           1.7.1
Installed devices:
- default.gaussian (PennyLane-0.22.1)
- default.mixed (PennyLane-0.22.1)
- default.qubit (PennyLane-0.22.1)
- default.qubit.autograd (PennyLane-0.22.1)
- default.qubit.jax (PennyLane-0.22.1)
- default.qubit.tf (PennyLane-0.22.1)
- default.qubit.torch (PennyLane-0.22.1)
- lightning.qubit (PennyLane-Lightning-0.22.1)
```


### Existing GitHub issues

- [X] I have searched existing GitHub issues to make sure the issue does not already exist.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pennylane/transforms/specs.py`
Content:
```
1 # Copyright 2018-2021 Xanadu Quantum Technologies Inc.
2 
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 """Code for resource estimation"""
15 import inspect
16 
17 import pennylane as qml
18 
19 
20 def _get_absolute_import_path(fn):
21     return f"{inspect.getmodule(fn).__name__}.{fn.__name__}"
22 
23 
24 def specs(qnode, max_expansion=None):
25     """Resource information about a quantum circuit.
26 
27     This transform converts a QNode into a callable that provides resource information
28     about the circuit.
29 
30     Args:
31         qnode (.QNode): the QNode to calculate the specifications for
32 
33     Keyword Args:
34         max_expansion (int): The number of times the internal circuit should be expanded when
35             calculating the specification. Defaults to ``qnode.max_expansion``.
36 
37     Returns:
38         A function that has the same argument signature as ``qnode``. This function
39         returns a dictionary of information about qnode structure.
40 
41     **Example**
42 
43     .. code-block:: python3
44 
45         x = np.array([0.1, 0.2])
46 
47         dev = qml.device('default.qubit', wires=2)
48         @qml.qnode(dev, diff_method="parameter-shift", shift=np.pi / 4)
49         def circuit(x, add_ry=True):
50             qml.RX(x[0], wires=0)
51             qml.CNOT(wires=(0,1))
52             if add_ry:
53                 qml.RY(x[1], wires=1)
54             return qml.probs(wires=(0,1))
55 
56     >>> qml.specs(circuit)(x, add_ry=False)
57     {'gate_sizes': defaultdict(int, {1: 1, 2: 1}),
58      'gate_types': defaultdict(int, {'RX': 1, 'CNOT': 1}),
59      'num_operations': 2,
60      'num_observables': 1,
61      'num_diagonalizing_gates': 0,
62      'num_used_wires': 2,
63      'depth': 2,
64      'num_trainable_params': 1,
65      'num_device_wires': 2,
66      'device_name': 'default.qubit',
67      'diff_method': 'parameter-shift',
68      'expansion_strategy': 'gradient',
69      'gradient_options': {'shift': 0.7853981633974483},
70      'interface': 'autograd',
71      'gradient_fn': 'pennylane.gradients.parameter_shift.param_shift',
72      'num_gradient_executions': 2}
73 
74     """
75 
76     def specs_qnode(*args, **kwargs):
77         """Returns information on the structure and makeup of provided QNode.
78 
79         Dictionary keys:
80             * ``"num_operations"``
81             * ``"num_observables"``
82             * ``"num_diagonalizing_gates"``
83             * ``"gate_sizes"``: dictionary mapping gate number of wires to number of occurances
84             * ``"gate_types"``: dictionary mapping gate types to number of occurances
85             * ``"num_used_wires"``: number of wires used by the circuit
86             * ``"num_device_wires"``: number of wires in device
87             * ``"depth"``: longest path in directed acyclic graph representation
88             * ``"dev_short_name"``: name of QNode device
89             * ``"diff_method"``
90 
91         Potential Additional Information:
92             * ``"num_trainable_params"``: number of individual scalars that are trainable
93             * ``"num_parameter_shift_executions"``: number of times circuit will execute when
94                     calculating the derivative
95 
96         Returns:
97             dict[str, Union[defaultdict,int]]: dictionaries that contain QNode specifications
98         """
99         initial_max_expansion = qnode.max_expansion
100         qnode.max_expansion = initial_max_expansion if max_expansion is None else max_expansion
101 
102         try:
103             qnode.construct(args, kwargs)
104         finally:
105             qnode.max_expansion = initial_max_expansion
106 
107         info = qnode.qtape.specs.copy()
108 
109         info["num_device_wires"] = qnode.device.num_wires
110         info["device_name"] = qnode.device.short_name
111         info["expansion_strategy"] = qnode.expansion_strategy
112         info["gradient_options"] = qnode.gradient_kwargs
113         info["interface"] = qnode.interface
114         info["diff_method"] = (
115             _get_absolute_import_path(qnode.diff_method)
116             if callable(qnode.diff_method)
117             else qnode.diff_method
118         )
119 
120         if isinstance(qnode.gradient_fn, qml.gradients.gradient_transform):
121             info["gradient_fn"] = _get_absolute_import_path(qnode.gradient_fn)
122 
123             try:
124                 info["num_gradient_executions"] = len(qnode.gradient_fn(qnode.qtape)[0])
125             except Exception as e:  # pylint: disable=broad-except
126                 # In the case of a broad exception, we don't want the `qml.specs` transform
127                 # to fail. Instead, we simply indicate that the number of gradient executions
128                 # is not supported for the reason specified.
129                 info["num_gradient_executions"] = f"NotSupported: {str(e)}"
130         else:
131             info["gradient_fn"] = qnode.gradient_fn
132 
133         return info
134 
135     return specs_qnode
136
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pennylane/transforms/specs.py b/pennylane/transforms/specs.py
--- a/pennylane/transforms/specs.py
+++ b/pennylane/transforms/specs.py
@@ -21,7 +21,7 @@
     return f"{inspect.getmodule(fn).__name__}.{fn.__name__}"
 
 
-def specs(qnode, max_expansion=None):
+def specs(qnode, max_expansion=None, expansion_strategy=None):
     """Resource information about a quantum circuit.
 
     This transform converts a QNode into a callable that provides resource information
@@ -33,6 +33,15 @@
     Keyword Args:
         max_expansion (int): The number of times the internal circuit should be expanded when
             calculating the specification. Defaults to ``qnode.max_expansion``.
+        expansion_strategy (str): The strategy to use when circuit expansions or decompositions
+            are required.
+
+            - ``gradient``: The QNode will attempt to decompose
+              the internal circuit such that all circuit operations are supported by the gradient
+              method.
+
+            - ``device``: The QNode will attempt to decompose the internal circuit
+              such that all circuit operations are natively supported by the device.
 
     Returns:
         A function that has the same argument signature as ``qnode``. This function
@@ -97,12 +106,15 @@
             dict[str, Union[defaultdict,int]]: dictionaries that contain QNode specifications
         """
         initial_max_expansion = qnode.max_expansion
-        qnode.max_expansion = initial_max_expansion if max_expansion is None else max_expansion
+        initial_expansion_strategy = getattr(qnode, "expansion_strategy", None)
 
         try:
+            qnode.max_expansion = initial_max_expansion if max_expansion is None else max_expansion
+            qnode.expansion_strategy = expansion_strategy or initial_expansion_strategy
             qnode.construct(args, kwargs)
         finally:
             qnode.max_expansion = initial_max_expansion
+            qnode.expansion_strategy = initial_expansion_strategy
 
         info = qnode.qtape.specs.copy()

{"golden_diff": "diff --git a/pennylane/transforms/specs.py b/pennylane/transforms/specs.py\n--- a/pennylane/transforms/specs.py\n+++ b/pennylane/transforms/specs.py\n@@ -21,7 +21,7 @@\n     return f\"{inspect.getmodule(fn).__name__}.{fn.__name__}\"\n \n \n-def specs(qnode, max_expansion=None):\n+def specs(qnode, max_expansion=None, expansion_strategy=None):\n     \"\"\"Resource information about a quantum circuit.\n \n     This transform converts a QNode into a callable that provides resource information\n@@ -33,6 +33,15 @@\n     Keyword Args:\n         max_expansion (int): The number of times the internal circuit should be expanded when\n             calculating the specification. Defaults to ``qnode.max_expansion``.\n+        expansion_strategy (str): The strategy to use when circuit expansions or decompositions\n+            are required.\n+\n+            - ``gradient``: The QNode will attempt to decompose\n+              the internal circuit such that all circuit operations are supported by the gradient\n+              method.\n+\n+            - ``device``: The QNode will attempt to decompose the internal circuit\n+              such that all circuit operations are natively supported by the device.\n \n     Returns:\n         A function that has the same argument signature as ``qnode``. This function\n@@ -97,12 +106,15 @@\n             dict[str, Union[defaultdict,int]]: dictionaries that contain QNode specifications\n         \"\"\"\n         initial_max_expansion = qnode.max_expansion\n-        qnode.max_expansion = initial_max_expansion if max_expansion is None else max_expansion\n+        initial_expansion_strategy = getattr(qnode, \"expansion_strategy\", None)\n \n         try:\n+            qnode.max_expansion = initial_max_expansion if max_expansion is None else max_expansion\n+            qnode.expansion_strategy = expansion_strategy or initial_expansion_strategy\n             qnode.construct(args, kwargs)\n         finally:\n             qnode.max_expansion = initial_max_expansion\n+            qnode.expansion_strategy = initial_expansion_strategy\n \n         info = qnode.qtape.specs.copy()\n", "issue": "[BUG] `qml.specs`: `max_expansion` keyword argument is not doing anything (what should it do?)\n### Expected behavior\n\nI'm not sure what `max_expansion` should be doing. Currently, it looks like it isn't doing anything. Maybe just the docstring\r\n\r\n> - max_expansion (int) \u2013 The number of times the internal circuit should be expanded when calculating the specification. Defaults to qnode.max_expansion.\r\n\r\ncan be clarified?\n\n### Actual behavior\n\nConsider this circuit:\r\n\r\n```\r\n@qml.qnode(dev)\r\ndef circuit():\r\n    qml.templates.StronglyEntanglingLayers(\r\n        np.random.random((3, 2, 3)),\r\n        wires=range(2)\r\n    )\r\n    return qml.probs(wires=(0,1))\r\n```\r\n\r\nThen, \r\n\r\n```\r\nprint(qml.specs(circuit)() == qml.specs(circuit, max_expansion=7)()) # output: True\r\n```\r\n\r\nno matter what the value `max_expansion` is assigned to.\r\n\r\n\n\n### Additional information\n\nSpecifying `expansion_strategy = \"device\"` below updates the `'depth'` key:\r\n\r\n```\r\n@qml.qnode(dev, expansion_strategy=\"device\")\r\ndef circuit():\r\n    qml.templates.StronglyEntanglingLayers(\r\n        np.random.random((3, 2, 3)),\r\n        wires=range(2)\r\n    )\r\n    return qml.probs(wires=(0,1))\r\n\r\nprint(qml.specs(circuit)()) # 'depth' key is changed from 1 (without expansion_strategy) to 9\r\n```\n\n### Source code\n\n```shell\nimport pennylane as qml\r\nfrom pennylane import numpy as np\r\n\r\ndev = qml.device('default.qubit', wires=2)\r\n\r\ndef layer():\r\n    qml.templates.StronglyEntanglingLayers(\r\n        np.random.random((3, 2, 3)),\r\n        wires=range(2)\r\n    )\r\n\r\n@qml.qnode(dev, expansion_strategy=\"device\")\r\ndef circuit_exp_strat():\r\n    layer()\r\n    return qml.probs(wires=(0,1))\r\n\r\n@qml.qnode(dev)\r\ndef circuit():\r\n    layer()\r\n    return qml.probs(wires=(0,1))\r\n\r\nprint(qml.specs(circuit_exp_strat)())\r\nprint(qml.specs(circuit)())\r\nprint(qml.specs(circuit, max_expansion = 7)())\n```\n\n\n### Tracebacks\n\n```shell\nN/A\n```\n\n\n### System information\n\n```shell\nName: PennyLane\r\nVersion: 0.22.1\r\nSummary: PennyLane is a Python quantum machine learning library by Xanadu Inc.\r\nHome-page: https://github.com/XanaduAI/pennylane\r\nAuthor: \r\nAuthor-email: \r\nLicense: Apache License 2.0\r\nLocation: /opt/anaconda3/lib/python3.9/site-packages\r\nRequires: toml, appdirs, retworkx, pennylane-lightning, numpy, autograd, semantic-version, networkx, scipy, autoray, cachetools\r\nRequired-by: PennyLane-Lightning\r\nPlatform info:           macOS-10.16-x86_64-i386-64bit\r\nPython version:          3.9.7\r\nNumpy version:           1.20.3\r\nScipy version:           1.7.1\r\nInstalled devices:\r\n- default.gaussian (PennyLane-0.22.1)\r\n- default.mixed (PennyLane-0.22.1)\r\n- default.qubit (PennyLane-0.22.1)\r\n- default.qubit.autograd (PennyLane-0.22.1)\r\n- default.qubit.jax (PennyLane-0.22.1)\r\n- default.qubit.tf (PennyLane-0.22.1)\r\n- default.qubit.torch (PennyLane-0.22.1)\r\n- lightning.qubit (PennyLane-Lightning-0.22.1)\n```\n\n\n### Existing GitHub issues\n\n- [X] I have searched existing GitHub issues to make sure the issue does not already exist.\n", "before_files": [{"content": "# Copyright 2018-2021 Xanadu Quantum Technologies Inc.\n\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n\n#     http://www.apache.org/licenses/LICENSE-2.0\n\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"Code for resource estimation\"\"\"\nimport inspect\n\nimport pennylane as qml\n\n\ndef _get_absolute_import_path(fn):\n    return f\"{inspect.getmodule(fn).__name__}.{fn.__name__}\"\n\n\ndef specs(qnode, max_expansion=None):\n    \"\"\"Resource information about a quantum circuit.\n\n    This transform converts a QNode into a callable that provides resource information\n    about the circuit.\n\n    Args:\n        qnode (.QNode): the QNode to calculate the specifications for\n\n    Keyword Args:\n        max_expansion (int): The number of times the internal circuit should be expanded when\n            calculating the specification. Defaults to ``qnode.max_expansion``.\n\n    Returns:\n        A function that has the same argument signature as ``qnode``. This function\n        returns a dictionary of information about qnode structure.\n\n    **Example**\n\n    .. code-block:: python3\n\n        x = np.array([0.1, 0.2])\n\n        dev = qml.device('default.qubit', wires=2)\n        @qml.qnode(dev, diff_method=\"parameter-shift\", shift=np.pi / 4)\n        def circuit(x, add_ry=True):\n            qml.RX(x[0], wires=0)\n            qml.CNOT(wires=(0,1))\n            if add_ry:\n                qml.RY(x[1], wires=1)\n            return qml.probs(wires=(0,1))\n\n    >>> qml.specs(circuit)(x, add_ry=False)\n    {'gate_sizes': defaultdict(int, {1: 1, 2: 1}),\n     'gate_types': defaultdict(int, {'RX': 1, 'CNOT': 1}),\n     'num_operations': 2,\n     'num_observables': 1,\n     'num_diagonalizing_gates': 0,\n     'num_used_wires': 2,\n     'depth': 2,\n     'num_trainable_params': 1,\n     'num_device_wires': 2,\n     'device_name': 'default.qubit',\n     'diff_method': 'parameter-shift',\n     'expansion_strategy': 'gradient',\n     'gradient_options': {'shift': 0.7853981633974483},\n     'interface': 'autograd',\n     'gradient_fn': 'pennylane.gradients.parameter_shift.param_shift',\n     'num_gradient_executions': 2}\n\n    \"\"\"\n\n    def specs_qnode(*args, **kwargs):\n        \"\"\"Returns information on the structure and makeup of provided QNode.\n\n        Dictionary keys:\n            * ``\"num_operations\"``\n            * ``\"num_observables\"``\n            * ``\"num_diagonalizing_gates\"``\n            * ``\"gate_sizes\"``: dictionary mapping gate number of wires to number of occurances\n            * ``\"gate_types\"``: dictionary mapping gate types to number of occurances\n            * ``\"num_used_wires\"``: number of wires used by the circuit\n            * ``\"num_device_wires\"``: number of wires in device\n            * ``\"depth\"``: longest path in directed acyclic graph representation\n            * ``\"dev_short_name\"``: name of QNode device\n            * ``\"diff_method\"``\n\n        Potential Additional Information:\n            * ``\"num_trainable_params\"``: number of individual scalars that are trainable\n            * ``\"num_parameter_shift_executions\"``: number of times circuit will execute when\n                    calculating the derivative\n\n        Returns:\n            dict[str, Union[defaultdict,int]]: dictionaries that contain QNode specifications\n        \"\"\"\n        initial_max_expansion = qnode.max_expansion\n        qnode.max_expansion = initial_max_expansion if max_expansion is None else max_expansion\n\n        try:\n            qnode.construct(args, kwargs)\n        finally:\n            qnode.max_expansion = initial_max_expansion\n\n        info = qnode.qtape.specs.copy()\n\n        info[\"num_device_wires\"] = qnode.device.num_wires\n        info[\"device_name\"] = qnode.device.short_name\n        info[\"expansion_strategy\"] = qnode.expansion_strategy\n        info[\"gradient_options\"] = qnode.gradient_kwargs\n        info[\"interface\"] = qnode.interface\n        info[\"diff_method\"] = (\n            _get_absolute_import_path(qnode.diff_method)\n            if callable(qnode.diff_method)\n            else qnode.diff_method\n        )\n\n        if isinstance(qnode.gradient_fn, qml.gradients.gradient_transform):\n            info[\"gradient_fn\"] = _get_absolute_import_path(qnode.gradient_fn)\n\n            try:\n                info[\"num_gradient_executions\"] = len(qnode.gradient_fn(qnode.qtape)[0])\n            except Exception as e:  # pylint: disable=broad-except\n                # In the case of a broad exception, we don't want the `qml.specs` transform\n                # to fail. Instead, we simply indicate that the number of gradient executions\n                # is not supported for the reason specified.\n                info[\"num_gradient_executions\"] = f\"NotSupported: {str(e)}\"\n        else:\n            info[\"gradient_fn\"] = qnode.gradient_fn\n\n        return info\n\n    return specs_qnode\n", "path": "pennylane/transforms/specs.py"}], "after_files": [{"content": "# Copyright 2018-2021 Xanadu Quantum Technologies Inc.\n\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n\n#     http://www.apache.org/licenses/LICENSE-2.0\n\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"Code for resource estimation\"\"\"\nimport inspect\n\nimport pennylane as qml\n\n\ndef _get_absolute_import_path(fn):\n    return f\"{inspect.getmodule(fn).__name__}.{fn.__name__}\"\n\n\ndef specs(qnode, max_expansion=None, expansion_strategy=None):\n    \"\"\"Resource information about a quantum circuit.\n\n    This transform converts a QNode into a callable that provides resource information\n    about the circuit.\n\n    Args:\n        qnode (.QNode): the QNode to calculate the specifications for\n\n    Keyword Args:\n        max_expansion (int): The number of times the internal circuit should be expanded when\n            calculating the specification. Defaults to ``qnode.max_expansion``.\n        expansion_strategy (str): The strategy to use when circuit expansions or decompositions\n            are required.\n\n            - ``gradient``: The QNode will attempt to decompose\n              the internal circuit such that all circuit operations are supported by the gradient\n              method.\n\n            - ``device``: The QNode will attempt to decompose the internal circuit\n              such that all circuit operations are natively supported by the device.\n\n    Returns:\n        A function that has the same argument signature as ``qnode``. This function\n        returns a dictionary of information about qnode structure.\n\n    **Example**\n\n    .. code-block:: python3\n\n        x = np.array([0.1, 0.2])\n\n        dev = qml.device('default.qubit', wires=2)\n        @qml.qnode(dev, diff_method=\"parameter-shift\", shift=np.pi / 4)\n        def circuit(x, add_ry=True):\n            qml.RX(x[0], wires=0)\n            qml.CNOT(wires=(0,1))\n            if add_ry:\n                qml.RY(x[1], wires=1)\n            return qml.probs(wires=(0,1))\n\n    >>> qml.specs(circuit)(x, add_ry=False)\n    {'gate_sizes': defaultdict(int, {1: 1, 2: 1}),\n     'gate_types': defaultdict(int, {'RX': 1, 'CNOT': 1}),\n     'num_operations': 2,\n     'num_observables': 1,\n     'num_diagonalizing_gates': 0,\n     'num_used_wires': 2,\n     'depth': 2,\n     'num_trainable_params': 1,\n     'num_device_wires': 2,\n     'device_name': 'default.qubit',\n     'diff_method': 'parameter-shift',\n     'expansion_strategy': 'gradient',\n     'gradient_options': {'shift': 0.7853981633974483},\n     'interface': 'autograd',\n     'gradient_fn': 'pennylane.gradients.parameter_shift.param_shift',\n     'num_gradient_executions': 2}\n\n    \"\"\"\n\n    def specs_qnode(*args, **kwargs):\n        \"\"\"Returns information on the structure and makeup of provided QNode.\n\n        Dictionary keys:\n            * ``\"num_operations\"``\n            * ``\"num_observables\"``\n            * ``\"num_diagonalizing_gates\"``\n            * ``\"gate_sizes\"``: dictionary mapping gate number of wires to number of occurances\n            * ``\"gate_types\"``: dictionary mapping gate types to number of occurances\n            * ``\"num_used_wires\"``: number of wires used by the circuit\n            * ``\"num_device_wires\"``: number of wires in device\n            * ``\"depth\"``: longest path in directed acyclic graph representation\n            * ``\"dev_short_name\"``: name of QNode device\n            * ``\"diff_method\"``\n\n        Potential Additional Information:\n            * ``\"num_trainable_params\"``: number of individual scalars that are trainable\n            * ``\"num_parameter_shift_executions\"``: number of times circuit will execute when\n                    calculating the derivative\n\n        Returns:\n            dict[str, Union[defaultdict,int]]: dictionaries that contain QNode specifications\n        \"\"\"\n        initial_max_expansion = qnode.max_expansion\n        initial_expansion_strategy = getattr(qnode, \"expansion_strategy\", None)\n\n        try:\n            qnode.max_expansion = initial_max_expansion if max_expansion is None else max_expansion\n            qnode.expansion_strategy = expansion_strategy or initial_expansion_strategy\n            qnode.construct(args, kwargs)\n        finally:\n            qnode.max_expansion = initial_max_expansion\n            qnode.expansion_strategy = initial_expansion_strategy\n\n        info = qnode.qtape.specs.copy()\n\n        info[\"num_device_wires\"] = qnode.device.num_wires\n        info[\"device_name\"] = qnode.device.short_name\n        info[\"expansion_strategy\"] = qnode.expansion_strategy\n        info[\"gradient_options\"] = qnode.gradient_kwargs\n        info[\"interface\"] = qnode.interface\n        info[\"diff_method\"] = (\n            _get_absolute_import_path(qnode.diff_method)\n            if callable(qnode.diff_method)\n            else qnode.diff_method\n        )\n\n        if isinstance(qnode.gradient_fn, qml.gradients.gradient_transform):\n            info[\"gradient_fn\"] = _get_absolute_import_path(qnode.gradient_fn)\n\n            try:\n                info[\"num_gradient_executions\"] = len(qnode.gradient_fn(qnode.qtape)[0])\n            except Exception as e:  # pylint: disable=broad-except\n                # In the case of a broad exception, we don't want the `qml.specs` transform\n                # to fail. Instead, we simply indicate that the number of gradient executions\n                # is not supported for the reason specified.\n                info[\"num_gradient_executions\"] = f\"NotSupported: {str(e)}\"\n        else:\n            info[\"gradient_fn\"] = qnode.gradient_fn\n\n        return info\n\n    return specs_qnode\n", "path": "pennylane/transforms/specs.py"}]}