prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  __call__ using ClassWrapper does not update wrapped metric
  ## 🐛 Bug
  
  Using __call__ with ClasswiseWrapper does not update the Metric within, such that subsequent calls to compute are only using the last batch input.
  
  ### To Reproduce
  
  See code sample
  
  #### Code sample
  
  ```py
  import numpy as np
  import torch
  import torchmetrics
  
  np.random.seed(42)
  
  m1 = torchmetrics.Precision(num_classes=3, average=None)
  m2 = torchmetrics.Precision(num_classes=3, average=None)
  mcw1 = torchmetrics.ClasswiseWrapper(torchmetrics.Precision(num_classes=3, average=None))
  mcw2 = torchmetrics.ClasswiseWrapper(torchmetrics.Precision(num_classes=3, average=None))
  
  for i in range(2):
      print(f"Epoch: {i}")
      preds = torch.Tensor(np.random.uniform(0, 1, (100, 3)))
      targets = torch.Tensor(np.random.randint(0, 2, (100, 3))).int()
      m1(preds, targets)
      m2.update(preds, targets)
      mcw1(preds, targets)
      mcw2.update(preds, targets)
      print(f"Prec:             {m1.compute().numpy()}")
      print(f"Prec update:      {m2.compute().numpy()}")
      print(f"Prec wrap:        {np.asarray([v.numpy() for v in mcw1.compute().values()])}")
      print(f"Prec wrap update: {np.asarray([v.numpy() for v in mcw2.compute().values()])}")
  ```
  
  Output is:
  
  ```
  Epoch: 0
  Prec:             [0.42857143 0.537037   0.509434  ]
  Prec update:      [0.42857143 0.537037   0.509434  ]
  Prec wrap:        [0.42857143 0.537037   0.509434  ]
  Prec wrap update: [0.42857143 0.537037   0.509434  ]
  Epoch: 1
  Prec:             [0.46464646 0.5247525  0.48039216]
  Prec update:      [0.46464646 0.5247525  0.48039216]
  Prec wrap:        [0.5       0.5106383 0.4489796]
  Prec wrap update: [0.46464646 0.5247525  0.48039216]
  ```
  
  ### Expected behavior
  
  The values should be the same whether calling `update` or `__call__`
  
  ### Environment
  
  - TorchMetrics version: 0.9.3
  - Python & PyTorch Version (e.g., 1.0): 1.12.0
  - Any other relevant information such as OS (e.g., Linux): Ubuntu 20.04
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `src/torchmetrics/wrappers/classwise.py`
  Content:
  ```
  1 from typing import Any, Dict, List, Optional
  2 
  3 from torch import Tensor
  4 
  5 from torchmetrics import Metric
  6 
  7 
  8 class ClasswiseWrapper(Metric):
  9     """Wrapper class for altering the output of classification metrics that returns multiple values to include
  10     label information.
  11 
  12     Args:
  13         metric: base metric that should be wrapped. It is assumed that the metric outputs a single
  14             tensor that is split along the first dimension.
  15         labels: list of strings indicating the different classes.
  16 
  17     Example:
  18         >>> import torch
  19         >>> _ = torch.manual_seed(42)
  20         >>> from torchmetrics import Accuracy, ClasswiseWrapper
  21         >>> metric = ClasswiseWrapper(Accuracy(num_classes=3, average=None))
  22         >>> preds = torch.randn(10, 3).softmax(dim=-1)
  23         >>> target = torch.randint(3, (10,))
  24         >>> metric(preds, target)
  25         {'accuracy_0': tensor(0.5000), 'accuracy_1': tensor(0.7500), 'accuracy_2': tensor(0.)}
  26 
  27     Example (labels as list of strings):
  28         >>> import torch
  29         >>> from torchmetrics import Accuracy, ClasswiseWrapper
  30         >>> metric = ClasswiseWrapper(
  31         ...    Accuracy(num_classes=3, average=None),
  32         ...    labels=["horse", "fish", "dog"]
  33         ... )
  34         >>> preds = torch.randn(10, 3).softmax(dim=-1)
  35         >>> target = torch.randint(3, (10,))
  36         >>> metric(preds, target)
  37         {'accuracy_horse': tensor(0.3333), 'accuracy_fish': tensor(0.6667), 'accuracy_dog': tensor(0.)}
  38 
  39     Example (in metric collection):
  40         >>> import torch
  41         >>> from torchmetrics import Accuracy, ClasswiseWrapper, MetricCollection, Recall
  42         >>> labels = ["horse", "fish", "dog"]
  43         >>> metric = MetricCollection(
  44         ...     {'accuracy': ClasswiseWrapper(Accuracy(num_classes=3, average=None), labels),
  45         ...     'recall': ClasswiseWrapper(Recall(num_classes=3, average=None), labels)}
  46         ... )
  47         >>> preds = torch.randn(10, 3).softmax(dim=-1)
  48         >>> target = torch.randint(3, (10,))
  49         >>> metric(preds, target)  # doctest: +NORMALIZE_WHITESPACE
  50         {'accuracy_horse': tensor(0.), 'accuracy_fish': tensor(0.3333), 'accuracy_dog': tensor(0.4000),
  51         'recall_horse': tensor(0.), 'recall_fish': tensor(0.3333), 'recall_dog': tensor(0.4000)}
  52     """
  53 
  54     full_state_update: Optional[bool] = True
  55 
  56     def __init__(self, metric: Metric, labels: Optional[List[str]] = None) -> None:
  57         super().__init__()
  58         if not isinstance(metric, Metric):
  59             raise ValueError(f"Expected argument `metric` to be an instance of `torchmetrics.Metric` but got {metric}")
  60         if labels is not None and not (isinstance(labels, list) and all(isinstance(lab, str) for lab in labels)):
  61             raise ValueError(f"Expected argument `labels` to either be `None` or a list of strings but got {labels}")
  62         self.metric = metric
  63         self.labels = labels
  64 
  65     def _convert(self, x: Tensor) -> Dict[str, Any]:
  66         name = self.metric.__class__.__name__.lower()
  67         if self.labels is None:
  68             return {f"{name}_{i}": val for i, val in enumerate(x)}
  69         return {f"{name}_{lab}": val for lab, val in zip(self.labels, x)}
  70 
  71     def update(self, *args: Any, **kwargs: Any) -> None:
  72         self.metric.update(*args, **kwargs)
  73 
  74     def compute(self) -> Dict[str, Tensor]:
  75         return self._convert(self.metric.compute())
  76 
  77     def reset(self) -> None:
  78         self.metric.reset()
  79
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/src/torchmetrics/wrappers/classwise.py b/src/torchmetrics/wrappers/classwise.py
  --- a/src/torchmetrics/wrappers/classwise.py
  +++ b/src/torchmetrics/wrappers/classwise.py
  @@ -1,4 +1,17 @@
  -from typing import Any, Dict, List, Optional
  +# Copyright The PyTorch Lightning team.
  +#
  +# Licensed under the Apache License, Version 2.0 (the "License");
  +# you may not use this file except in compliance with the License.
  +# You may obtain a copy of the License at
  +#
  +#     http://www.apache.org/licenses/LICENSE-2.0
  +#
  +# Unless required by applicable law or agreed to in writing, software
  +# distributed under the License is distributed on an "AS IS" BASIS,
  +# 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.
  +from typing import Any, Callable, Dict, List, Optional
   
   from torch import Tensor
   
  @@ -51,8 +64,6 @@
           'recall_horse': tensor(0.), 'recall_fish': tensor(0.3333), 'recall_dog': tensor(0.4000)}
       """
   
  -    full_state_update: Optional[bool] = True
  -
       def __init__(self, metric: Metric, labels: Optional[List[str]] = None) -> None:
           super().__init__()
           if not isinstance(metric, Metric):
  @@ -61,6 +72,7 @@
               raise ValueError(f"Expected argument `labels` to either be `None` or a list of strings but got {labels}")
           self.metric = metric
           self.labels = labels
  +        self._update_count = 1
   
       def _convert(self, x: Tensor) -> Dict[str, Any]:
           name = self.metric.__class__.__name__.lower()
  @@ -68,6 +80,9 @@
               return {f"{name}_{i}": val for i, val in enumerate(x)}
           return {f"{name}_{lab}": val for lab, val in zip(self.labels, x)}
   
  +    def forward(self, *args: Any, **kwargs: Any) -> Any:
  +        return self._convert(self.metric(*args, **kwargs))
  +
       def update(self, *args: Any, **kwargs: Any) -> None:
           self.metric.update(*args, **kwargs)
   
  @@ -76,3 +91,11 @@
   
       def reset(self) -> None:
           self.metric.reset()
  +
  +    def _wrap_update(self, update: Callable) -> Callable:
  +        """Overwrite to do nothing."""
  +        return update
  +
  +    def _wrap_compute(self, compute: Callable) -> Callable:
  +        """Overwrite to do nothing."""
  +        return compute
  
verification_info: {"golden_diff": "diff --git a/src/torchmetrics/wrappers/classwise.py b/src/torchmetrics/wrappers/classwise.py\n--- a/src/torchmetrics/wrappers/classwise.py\n+++ b/src/torchmetrics/wrappers/classwise.py\n@@ -1,4 +1,17 @@\n-from typing import Any, Dict, List, Optional\n+# Copyright The PyTorch Lightning team.\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+from typing import Any, Callable, Dict, List, Optional\n \n from torch import Tensor\n \n@@ -51,8 +64,6 @@\n         'recall_horse': tensor(0.), 'recall_fish': tensor(0.3333), 'recall_dog': tensor(0.4000)}\n     \"\"\"\n \n-    full_state_update: Optional[bool] = True\n-\n     def __init__(self, metric: Metric, labels: Optional[List[str]] = None) -> None:\n         super().__init__()\n         if not isinstance(metric, Metric):\n@@ -61,6 +72,7 @@\n             raise ValueError(f\"Expected argument `labels` to either be `None` or a list of strings but got {labels}\")\n         self.metric = metric\n         self.labels = labels\n+        self._update_count = 1\n \n     def _convert(self, x: Tensor) -> Dict[str, Any]:\n         name = self.metric.__class__.__name__.lower()\n@@ -68,6 +80,9 @@\n             return {f\"{name}_{i}\": val for i, val in enumerate(x)}\n         return {f\"{name}_{lab}\": val for lab, val in zip(self.labels, x)}\n \n+    def forward(self, *args: Any, **kwargs: Any) -> Any:\n+        return self._convert(self.metric(*args, **kwargs))\n+\n     def update(self, *args: Any, **kwargs: Any) -> None:\n         self.metric.update(*args, **kwargs)\n \n@@ -76,3 +91,11 @@\n \n     def reset(self) -> None:\n         self.metric.reset()\n+\n+    def _wrap_update(self, update: Callable) -> Callable:\n+        \"\"\"Overwrite to do nothing.\"\"\"\n+        return update\n+\n+    def _wrap_compute(self, compute: Callable) -> Callable:\n+        \"\"\"Overwrite to do nothing.\"\"\"\n+        return compute\n", "issue": "__call__ using ClassWrapper does not update wrapped metric\n## \ud83d\udc1b Bug\r\n\r\nUsing __call__ with ClasswiseWrapper does not update the Metric within, such that subsequent calls to compute are only using the last batch input.\r\n\r\n### To Reproduce\r\n\r\nSee code sample\r\n\r\n#### Code sample\r\n\r\n```py\r\nimport numpy as np\r\nimport torch\r\nimport torchmetrics\r\n\r\nnp.random.seed(42)\r\n\r\nm1 = torchmetrics.Precision(num_classes=3, average=None)\r\nm2 = torchmetrics.Precision(num_classes=3, average=None)\r\nmcw1 = torchmetrics.ClasswiseWrapper(torchmetrics.Precision(num_classes=3, average=None))\r\nmcw2 = torchmetrics.ClasswiseWrapper(torchmetrics.Precision(num_classes=3, average=None))\r\n\r\nfor i in range(2):\r\n    print(f\"Epoch: {i}\")\r\n    preds = torch.Tensor(np.random.uniform(0, 1, (100, 3)))\r\n    targets = torch.Tensor(np.random.randint(0, 2, (100, 3))).int()\r\n    m1(preds, targets)\r\n    m2.update(preds, targets)\r\n    mcw1(preds, targets)\r\n    mcw2.update(preds, targets)\r\n    print(f\"Prec:             {m1.compute().numpy()}\")\r\n    print(f\"Prec update:      {m2.compute().numpy()}\")\r\n    print(f\"Prec wrap:        {np.asarray([v.numpy() for v in mcw1.compute().values()])}\")\r\n    print(f\"Prec wrap update: {np.asarray([v.numpy() for v in mcw2.compute().values()])}\")\r\n```\r\n\r\nOutput is:\r\n\r\n```\r\nEpoch: 0\r\nPrec:             [0.42857143 0.537037   0.509434  ]\r\nPrec update:      [0.42857143 0.537037   0.509434  ]\r\nPrec wrap:        [0.42857143 0.537037   0.509434  ]\r\nPrec wrap update: [0.42857143 0.537037   0.509434  ]\r\nEpoch: 1\r\nPrec:             [0.46464646 0.5247525  0.48039216]\r\nPrec update:      [0.46464646 0.5247525  0.48039216]\r\nPrec wrap:        [0.5       0.5106383 0.4489796]\r\nPrec wrap update: [0.46464646 0.5247525  0.48039216]\r\n```\r\n\r\n### Expected behavior\r\n\r\nThe values should be the same whether calling `update` or `__call__`\r\n\r\n### Environment\r\n\r\n- TorchMetrics version: 0.9.3\r\n- Python & PyTorch Version (e.g., 1.0): 1.12.0\r\n- Any other relevant information such as OS (e.g., Linux): Ubuntu 20.04\r\n\n", "before_files": [{"content": "from typing import Any, Dict, List, Optional\n\nfrom torch import Tensor\n\nfrom torchmetrics import Metric\n\n\nclass ClasswiseWrapper(Metric):\n    \"\"\"Wrapper class for altering the output of classification metrics that returns multiple values to include\n    label information.\n\n    Args:\n        metric: base metric that should be wrapped. It is assumed that the metric outputs a single\n            tensor that is split along the first dimension.\n        labels: list of strings indicating the different classes.\n\n    Example:\n        >>> import torch\n        >>> _ = torch.manual_seed(42)\n        >>> from torchmetrics import Accuracy, ClasswiseWrapper\n        >>> metric = ClasswiseWrapper(Accuracy(num_classes=3, average=None))\n        >>> preds = torch.randn(10, 3).softmax(dim=-1)\n        >>> target = torch.randint(3, (10,))\n        >>> metric(preds, target)\n        {'accuracy_0': tensor(0.5000), 'accuracy_1': tensor(0.7500), 'accuracy_2': tensor(0.)}\n\n    Example (labels as list of strings):\n        >>> import torch\n        >>> from torchmetrics import Accuracy, ClasswiseWrapper\n        >>> metric = ClasswiseWrapper(\n        ...    Accuracy(num_classes=3, average=None),\n        ...    labels=[\"horse\", \"fish\", \"dog\"]\n        ... )\n        >>> preds = torch.randn(10, 3).softmax(dim=-1)\n        >>> target = torch.randint(3, (10,))\n        >>> metric(preds, target)\n        {'accuracy_horse': tensor(0.3333), 'accuracy_fish': tensor(0.6667), 'accuracy_dog': tensor(0.)}\n\n    Example (in metric collection):\n        >>> import torch\n        >>> from torchmetrics import Accuracy, ClasswiseWrapper, MetricCollection, Recall\n        >>> labels = [\"horse\", \"fish\", \"dog\"]\n        >>> metric = MetricCollection(\n        ...     {'accuracy': ClasswiseWrapper(Accuracy(num_classes=3, average=None), labels),\n        ...     'recall': ClasswiseWrapper(Recall(num_classes=3, average=None), labels)}\n        ... )\n        >>> preds = torch.randn(10, 3).softmax(dim=-1)\n        >>> target = torch.randint(3, (10,))\n        >>> metric(preds, target)  # doctest: +NORMALIZE_WHITESPACE\n        {'accuracy_horse': tensor(0.), 'accuracy_fish': tensor(0.3333), 'accuracy_dog': tensor(0.4000),\n        'recall_horse': tensor(0.), 'recall_fish': tensor(0.3333), 'recall_dog': tensor(0.4000)}\n    \"\"\"\n\n    full_state_update: Optional[bool] = True\n\n    def __init__(self, metric: Metric, labels: Optional[List[str]] = None) -> None:\n        super().__init__()\n        if not isinstance(metric, Metric):\n            raise ValueError(f\"Expected argument `metric` to be an instance of `torchmetrics.Metric` but got {metric}\")\n        if labels is not None and not (isinstance(labels, list) and all(isinstance(lab, str) for lab in labels)):\n            raise ValueError(f\"Expected argument `labels` to either be `None` or a list of strings but got {labels}\")\n        self.metric = metric\n        self.labels = labels\n\n    def _convert(self, x: Tensor) -> Dict[str, Any]:\n        name = self.metric.__class__.__name__.lower()\n        if self.labels is None:\n            return {f\"{name}_{i}\": val for i, val in enumerate(x)}\n        return {f\"{name}_{lab}\": val for lab, val in zip(self.labels, x)}\n\n    def update(self, *args: Any, **kwargs: Any) -> None:\n        self.metric.update(*args, **kwargs)\n\n    def compute(self) -> Dict[str, Tensor]:\n        return self._convert(self.metric.compute())\n\n    def reset(self) -> None:\n        self.metric.reset()\n", "path": "src/torchmetrics/wrappers/classwise.py"}], "after_files": [{"content": "# Copyright The PyTorch Lightning team.\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.\nfrom typing import Any, Callable, Dict, List, Optional\n\nfrom torch import Tensor\n\nfrom torchmetrics import Metric\n\n\nclass ClasswiseWrapper(Metric):\n    \"\"\"Wrapper class for altering the output of classification metrics that returns multiple values to include\n    label information.\n\n    Args:\n        metric: base metric that should be wrapped. It is assumed that the metric outputs a single\n            tensor that is split along the first dimension.\n        labels: list of strings indicating the different classes.\n\n    Example:\n        >>> import torch\n        >>> _ = torch.manual_seed(42)\n        >>> from torchmetrics import Accuracy, ClasswiseWrapper\n        >>> metric = ClasswiseWrapper(Accuracy(num_classes=3, average=None))\n        >>> preds = torch.randn(10, 3).softmax(dim=-1)\n        >>> target = torch.randint(3, (10,))\n        >>> metric(preds, target)\n        {'accuracy_0': tensor(0.5000), 'accuracy_1': tensor(0.7500), 'accuracy_2': tensor(0.)}\n\n    Example (labels as list of strings):\n        >>> import torch\n        >>> from torchmetrics import Accuracy, ClasswiseWrapper\n        >>> metric = ClasswiseWrapper(\n        ...    Accuracy(num_classes=3, average=None),\n        ...    labels=[\"horse\", \"fish\", \"dog\"]\n        ... )\n        >>> preds = torch.randn(10, 3).softmax(dim=-1)\n        >>> target = torch.randint(3, (10,))\n        >>> metric(preds, target)\n        {'accuracy_horse': tensor(0.3333), 'accuracy_fish': tensor(0.6667), 'accuracy_dog': tensor(0.)}\n\n    Example (in metric collection):\n        >>> import torch\n        >>> from torchmetrics import Accuracy, ClasswiseWrapper, MetricCollection, Recall\n        >>> labels = [\"horse\", \"fish\", \"dog\"]\n        >>> metric = MetricCollection(\n        ...     {'accuracy': ClasswiseWrapper(Accuracy(num_classes=3, average=None), labels),\n        ...     'recall': ClasswiseWrapper(Recall(num_classes=3, average=None), labels)}\n        ... )\n        >>> preds = torch.randn(10, 3).softmax(dim=-1)\n        >>> target = torch.randint(3, (10,))\n        >>> metric(preds, target)  # doctest: +NORMALIZE_WHITESPACE\n        {'accuracy_horse': tensor(0.), 'accuracy_fish': tensor(0.3333), 'accuracy_dog': tensor(0.4000),\n        'recall_horse': tensor(0.), 'recall_fish': tensor(0.3333), 'recall_dog': tensor(0.4000)}\n    \"\"\"\n\n    def __init__(self, metric: Metric, labels: Optional[List[str]] = None) -> None:\n        super().__init__()\n        if not isinstance(metric, Metric):\n            raise ValueError(f\"Expected argument `metric` to be an instance of `torchmetrics.Metric` but got {metric}\")\n        if labels is not None and not (isinstance(labels, list) and all(isinstance(lab, str) for lab in labels)):\n            raise ValueError(f\"Expected argument `labels` to either be `None` or a list of strings but got {labels}\")\n        self.metric = metric\n        self.labels = labels\n        self._update_count = 1\n\n    def _convert(self, x: Tensor) -> Dict[str, Any]:\n        name = self.metric.__class__.__name__.lower()\n        if self.labels is None:\n            return {f\"{name}_{i}\": val for i, val in enumerate(x)}\n        return {f\"{name}_{lab}\": val for lab, val in zip(self.labels, x)}\n\n    def forward(self, *args: Any, **kwargs: Any) -> Any:\n        return self._convert(self.metric(*args, **kwargs))\n\n    def update(self, *args: Any, **kwargs: Any) -> None:\n        self.metric.update(*args, **kwargs)\n\n    def compute(self) -> Dict[str, Tensor]:\n        return self._convert(self.metric.compute())\n\n    def reset(self) -> None:\n        self.metric.reset()\n\n    def _wrap_update(self, update: Callable) -> Callable:\n        \"\"\"Overwrite to do nothing.\"\"\"\n        return update\n\n    def _wrap_compute(self, compute: Callable) -> Callable:\n        \"\"\"Overwrite to do nothing.\"\"\"\n        return compute\n", "path": "src/torchmetrics/wrappers/classwise.py"}]}