We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add testing agains each feat PT version
## 🚀 Feature

Add a conda setup for testing against all PyTorch feature releases such as 1.4, 1.5, 1.6, ...

### Motivation

have better validation if some functions are not supported in old PT versions

### Pitch

<!-- A clear and concise description of what you want to happen. -->

### Alternatives

use CI action with conda setup, probably no need for pull large docker image

### Additional context

take inspiration from past Conda matrix in PL


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `integrations/lightning_models.py`
Content:
```
1 # Copyright The PyTorch Lightning team.
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 import torch
15 from pytorch_lightning import LightningModule
16 from torch.utils.data import Dataset
17 
18 
19 class RandomDictStringDataset(Dataset):
20 
21     def __init__(self, size, length):
22         self.len = length
23         self.data = torch.randn(length, size)
24 
25     def __getitem__(self, index):
26         return {"id": str(index), "x": self.data[index]}
27 
28     def __len__(self):
29         return self.len
30 
31 
32 class RandomDataset(Dataset):
33 
34     def __init__(self, size, length):
35         self.len = length
36         self.data = torch.randn(length, size)
37 
38     def __getitem__(self, index):
39         return self.data[index]
40 
41     def __len__(self):
42         return self.len
43 
44 
45 class BoringModel(LightningModule):
46 
47     def __init__(self):
48         """
49         Testing PL Module
50 
51         Use as follows:
52         - subclass
53         - modify the behavior for what you want
54 
55         class TestModel(BaseTestModel):
56             def training_step(...):
57                 # do your own thing
58 
59         or:
60 
61         model = BaseTestModel()
62         model.training_epoch_end = None
63 
64         """
65         super().__init__()
66         self.layer = torch.nn.Linear(32, 2)
67 
68     def forward(self, x):
69         return self.layer(x)
70 
71     @staticmethod
72     def loss(_, prediction):
73         # An arbitrary loss to have a loss that updates the model weights during `Trainer.fit` calls
74         return torch.nn.functional.mse_loss(prediction, torch.ones_like(prediction))
75 
76     def step(self, x):
77         x = self(x)
78         out = torch.nn.functional.mse_loss(x, torch.ones_like(x))
79         return out
80 
81     def training_step(self, batch, batch_idx):
82         output = self.layer(batch)
83         loss = self.loss(batch, output)
84         return {"loss": loss}
85 
86     def training_step_end(self, training_step_outputs):
87         return training_step_outputs
88 
89     def training_epoch_end(self, outputs) -> None:
90         torch.stack([x["loss"] for x in outputs]).mean()
91 
92     def validation_step(self, batch, batch_idx):
93         output = self.layer(batch)
94         loss = self.loss(batch, output)
95         return {"x": loss}
96 
97     def validation_epoch_end(self, outputs) -> None:
98         torch.stack([x['x'] for x in outputs]).mean()
99 
100     def test_step(self, batch, batch_idx):
101         output = self.layer(batch)
102         loss = self.loss(batch, output)
103         return {"y": loss}
104 
105     def test_epoch_end(self, outputs) -> None:
106         torch.stack([x["y"] for x in outputs]).mean()
107 
108     def configure_optimizers(self):
109         optimizer = torch.optim.SGD(self.layer.parameters(), lr=0.1)
110         lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=1)
111         return [optimizer], [lr_scheduler]
112 
113     def train_dataloader(self):
114         return torch.utils.data.DataLoader(RandomDataset(32, 64))
115 
116     def val_dataloader(self):
117         return torch.utils.data.DataLoader(RandomDataset(32, 64))
118 
119     def test_dataloader(self):
120         return torch.utils.data.DataLoader(RandomDataset(32, 64))
121
```

Path: `torchmetrics/utilities/imports.py`
Content:
```
1 from distutils.version import LooseVersion
2 
3 import torch
4 
5 _TORCH_LOWER_1_4 = LooseVersion(torch.__version__) < LooseVersion("1.4.0")
6 _TORCH_LOWER_1_5 = LooseVersion(torch.__version__) < LooseVersion("1.5.0")
7 _TORCH_LOWER_1_6 = LooseVersion(torch.__version__) < LooseVersion("1.6.0")
8
```

Path: `integrations/__init__.py`
Content:
```
```
--- 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/integrations/__init__.py b/integrations/__init__.py
--- a/integrations/__init__.py
+++ b/integrations/__init__.py
@@ -0,0 +1,3 @@
+from torchmetrics.utilities.imports import _module_available
+
+_PL_AVAILABLE = _module_available('pytorch_lightning')
diff --git a/integrations/lightning_models.py b/integrations/lightning_models.py
--- a/integrations/lightning_models.py
+++ b/integrations/lightning_models.py
@@ -11,6 +11,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
 import torch
 from pytorch_lightning import LightningModule
 from torch.utils.data import Dataset
diff --git a/torchmetrics/utilities/imports.py b/torchmetrics/utilities/imports.py
--- a/torchmetrics/utilities/imports.py
+++ b/torchmetrics/utilities/imports.py
@@ -1,6 +1,64 @@
+# 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 distutils.version import LooseVersion
+from importlib import import_module
+from importlib.util import find_spec
 
 import torch
+from pkg_resources import DistributionNotFound
+
+
+def _module_available(module_path: str) -> bool:
+    """
+    Check if a path is available in your environment
+
+    >>> _module_available('os')
+    True
+    >>> _module_available('bla.bla')
+    False
+    """
+    try:
+        return find_spec(module_path) is not None
+    except AttributeError:
+        # Python 3.6
+        return False
+    except ModuleNotFoundError:
+        # Python 3.7+
+        return False
+
+
+def _compare_version(package: str, op, version) -> bool:
+    """
+    Compare package version with some requirements
+
+    >>> import operator
+    >>> _compare_version("torch", operator.ge, "0.1")
+    True
+    """
+    try:
+        pkg = import_module(package)
+    except (ModuleNotFoundError, DistributionNotFound):
+        return False
+    try:
+        pkg_version = LooseVersion(pkg.__version__)
+    except AttributeError:
+        return False
+    if not (hasattr(pkg_version, "vstring") and hasattr(pkg_version, "version")):
+        # this is mock by sphinx, so it shall return True ro generate all summaries
+        return True
+    return op(pkg_version, LooseVersion(version))
+
 
 _TORCH_LOWER_1_4 = LooseVersion(torch.__version__) < LooseVersion("1.4.0")
 _TORCH_LOWER_1_5 = LooseVersion(torch.__version__) < LooseVersion("1.5.0")

{"golden_diff": "diff --git a/integrations/__init__.py b/integrations/__init__.py\n--- a/integrations/__init__.py\n+++ b/integrations/__init__.py\n@@ -0,0 +1,3 @@\n+from torchmetrics.utilities.imports import _module_available\n+\n+_PL_AVAILABLE = _module_available('pytorch_lightning')\ndiff --git a/integrations/lightning_models.py b/integrations/lightning_models.py\n--- a/integrations/lightning_models.py\n+++ b/integrations/lightning_models.py\n@@ -11,6 +11,7 @@\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+\n import torch\n from pytorch_lightning import LightningModule\n from torch.utils.data import Dataset\ndiff --git a/torchmetrics/utilities/imports.py b/torchmetrics/utilities/imports.py\n--- a/torchmetrics/utilities/imports.py\n+++ b/torchmetrics/utilities/imports.py\n@@ -1,6 +1,64 @@\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 distutils.version import LooseVersion\n+from importlib import import_module\n+from importlib.util import find_spec\n \n import torch\n+from pkg_resources import DistributionNotFound\n+\n+\n+def _module_available(module_path: str) -> bool:\n+    \"\"\"\n+    Check if a path is available in your environment\n+\n+    >>> _module_available('os')\n+    True\n+    >>> _module_available('bla.bla')\n+    False\n+    \"\"\"\n+    try:\n+        return find_spec(module_path) is not None\n+    except AttributeError:\n+        # Python 3.6\n+        return False\n+    except ModuleNotFoundError:\n+        # Python 3.7+\n+        return False\n+\n+\n+def _compare_version(package: str, op, version) -> bool:\n+    \"\"\"\n+    Compare package version with some requirements\n+\n+    >>> import operator\n+    >>> _compare_version(\"torch\", operator.ge, \"0.1\")\n+    True\n+    \"\"\"\n+    try:\n+        pkg = import_module(package)\n+    except (ModuleNotFoundError, DistributionNotFound):\n+        return False\n+    try:\n+        pkg_version = LooseVersion(pkg.__version__)\n+    except AttributeError:\n+        return False\n+    if not (hasattr(pkg_version, \"vstring\") and hasattr(pkg_version, \"version\")):\n+        # this is mock by sphinx, so it shall return True ro generate all summaries\n+        return True\n+    return op(pkg_version, LooseVersion(version))\n+\n \n _TORCH_LOWER_1_4 = LooseVersion(torch.__version__) < LooseVersion(\"1.4.0\")\n _TORCH_LOWER_1_5 = LooseVersion(torch.__version__) < LooseVersion(\"1.5.0\")\n", "issue": "Add testing agains each feat PT version\n## \ud83d\ude80 Feature\r\n\r\nAdd a conda setup for testing against all PyTorch feature releases such as 1.4, 1.5, 1.6, ...\r\n\r\n### Motivation\r\n\r\nhave better validation if some functions are not supported in old PT versions\r\n\r\n### Pitch\r\n\r\n<!-- A clear and concise description of what you want to happen. -->\r\n\r\n### Alternatives\r\n\r\nuse CI action with conda setup, probably no need for pull large docker image\r\n\r\n### Additional context\r\n\r\ntake inspiration from past Conda matrix in PL\r\n\n", "before_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.\nimport torch\nfrom pytorch_lightning import LightningModule\nfrom torch.utils.data import Dataset\n\n\nclass RandomDictStringDataset(Dataset):\n\n    def __init__(self, size, length):\n        self.len = length\n        self.data = torch.randn(length, size)\n\n    def __getitem__(self, index):\n        return {\"id\": str(index), \"x\": self.data[index]}\n\n    def __len__(self):\n        return self.len\n\n\nclass RandomDataset(Dataset):\n\n    def __init__(self, size, length):\n        self.len = length\n        self.data = torch.randn(length, size)\n\n    def __getitem__(self, index):\n        return self.data[index]\n\n    def __len__(self):\n        return self.len\n\n\nclass BoringModel(LightningModule):\n\n    def __init__(self):\n        \"\"\"\n        Testing PL Module\n\n        Use as follows:\n        - subclass\n        - modify the behavior for what you want\n\n        class TestModel(BaseTestModel):\n            def training_step(...):\n                # do your own thing\n\n        or:\n\n        model = BaseTestModel()\n        model.training_epoch_end = None\n\n        \"\"\"\n        super().__init__()\n        self.layer = torch.nn.Linear(32, 2)\n\n    def forward(self, x):\n        return self.layer(x)\n\n    @staticmethod\n    def loss(_, prediction):\n        # An arbitrary loss to have a loss that updates the model weights during `Trainer.fit` calls\n        return torch.nn.functional.mse_loss(prediction, torch.ones_like(prediction))\n\n    def step(self, x):\n        x = self(x)\n        out = torch.nn.functional.mse_loss(x, torch.ones_like(x))\n        return out\n\n    def training_step(self, batch, batch_idx):\n        output = self.layer(batch)\n        loss = self.loss(batch, output)\n        return {\"loss\": loss}\n\n    def training_step_end(self, training_step_outputs):\n        return training_step_outputs\n\n    def training_epoch_end(self, outputs) -> None:\n        torch.stack([x[\"loss\"] for x in outputs]).mean()\n\n    def validation_step(self, batch, batch_idx):\n        output = self.layer(batch)\n        loss = self.loss(batch, output)\n        return {\"x\": loss}\n\n    def validation_epoch_end(self, outputs) -> None:\n        torch.stack([x['x'] for x in outputs]).mean()\n\n    def test_step(self, batch, batch_idx):\n        output = self.layer(batch)\n        loss = self.loss(batch, output)\n        return {\"y\": loss}\n\n    def test_epoch_end(self, outputs) -> None:\n        torch.stack([x[\"y\"] for x in outputs]).mean()\n\n    def configure_optimizers(self):\n        optimizer = torch.optim.SGD(self.layer.parameters(), lr=0.1)\n        lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=1)\n        return [optimizer], [lr_scheduler]\n\n    def train_dataloader(self):\n        return torch.utils.data.DataLoader(RandomDataset(32, 64))\n\n    def val_dataloader(self):\n        return torch.utils.data.DataLoader(RandomDataset(32, 64))\n\n    def test_dataloader(self):\n        return torch.utils.data.DataLoader(RandomDataset(32, 64))\n", "path": "integrations/lightning_models.py"}, {"content": "from distutils.version import LooseVersion\n\nimport torch\n\n_TORCH_LOWER_1_4 = LooseVersion(torch.__version__) < LooseVersion(\"1.4.0\")\n_TORCH_LOWER_1_5 = LooseVersion(torch.__version__) < LooseVersion(\"1.5.0\")\n_TORCH_LOWER_1_6 = LooseVersion(torch.__version__) < LooseVersion(\"1.6.0\")\n", "path": "torchmetrics/utilities/imports.py"}, {"content": "", "path": "integrations/__init__.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.\n\nimport torch\nfrom pytorch_lightning import LightningModule\nfrom torch.utils.data import Dataset\n\n\nclass RandomDictStringDataset(Dataset):\n\n    def __init__(self, size, length):\n        self.len = length\n        self.data = torch.randn(length, size)\n\n    def __getitem__(self, index):\n        return {\"id\": str(index), \"x\": self.data[index]}\n\n    def __len__(self):\n        return self.len\n\n\nclass RandomDataset(Dataset):\n\n    def __init__(self, size, length):\n        self.len = length\n        self.data = torch.randn(length, size)\n\n    def __getitem__(self, index):\n        return self.data[index]\n\n    def __len__(self):\n        return self.len\n\n\nclass BoringModel(LightningModule):\n\n    def __init__(self):\n        \"\"\"\n        Testing PL Module\n\n        Use as follows:\n        - subclass\n        - modify the behavior for what you want\n\n        class TestModel(BaseTestModel):\n            def training_step(...):\n                # do your own thing\n\n        or:\n\n        model = BaseTestModel()\n        model.training_epoch_end = None\n\n        \"\"\"\n        super().__init__()\n        self.layer = torch.nn.Linear(32, 2)\n\n    def forward(self, x):\n        return self.layer(x)\n\n    @staticmethod\n    def loss(_, prediction):\n        # An arbitrary loss to have a loss that updates the model weights during `Trainer.fit` calls\n        return torch.nn.functional.mse_loss(prediction, torch.ones_like(prediction))\n\n    def step(self, x):\n        x = self(x)\n        out = torch.nn.functional.mse_loss(x, torch.ones_like(x))\n        return out\n\n    def training_step(self, batch, batch_idx):\n        output = self.layer(batch)\n        loss = self.loss(batch, output)\n        return {\"loss\": loss}\n\n    def training_step_end(self, training_step_outputs):\n        return training_step_outputs\n\n    def training_epoch_end(self, outputs) -> None:\n        torch.stack([x[\"loss\"] for x in outputs]).mean()\n\n    def validation_step(self, batch, batch_idx):\n        output = self.layer(batch)\n        loss = self.loss(batch, output)\n        return {\"x\": loss}\n\n    def validation_epoch_end(self, outputs) -> None:\n        torch.stack([x['x'] for x in outputs]).mean()\n\n    def test_step(self, batch, batch_idx):\n        output = self.layer(batch)\n        loss = self.loss(batch, output)\n        return {\"y\": loss}\n\n    def test_epoch_end(self, outputs) -> None:\n        torch.stack([x[\"y\"] for x in outputs]).mean()\n\n    def configure_optimizers(self):\n        optimizer = torch.optim.SGD(self.layer.parameters(), lr=0.1)\n        lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=1)\n        return [optimizer], [lr_scheduler]\n\n    def train_dataloader(self):\n        return torch.utils.data.DataLoader(RandomDataset(32, 64))\n\n    def val_dataloader(self):\n        return torch.utils.data.DataLoader(RandomDataset(32, 64))\n\n    def test_dataloader(self):\n        return torch.utils.data.DataLoader(RandomDataset(32, 64))\n", "path": "integrations/lightning_models.py"}, {"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 distutils.version import LooseVersion\nfrom importlib import import_module\nfrom importlib.util import find_spec\n\nimport torch\nfrom pkg_resources import DistributionNotFound\n\n\ndef _module_available(module_path: str) -> bool:\n    \"\"\"\n    Check if a path is available in your environment\n\n    >>> _module_available('os')\n    True\n    >>> _module_available('bla.bla')\n    False\n    \"\"\"\n    try:\n        return find_spec(module_path) is not None\n    except AttributeError:\n        # Python 3.6\n        return False\n    except ModuleNotFoundError:\n        # Python 3.7+\n        return False\n\n\ndef _compare_version(package: str, op, version) -> bool:\n    \"\"\"\n    Compare package version with some requirements\n\n    >>> import operator\n    >>> _compare_version(\"torch\", operator.ge, \"0.1\")\n    True\n    \"\"\"\n    try:\n        pkg = import_module(package)\n    except (ModuleNotFoundError, DistributionNotFound):\n        return False\n    try:\n        pkg_version = LooseVersion(pkg.__version__)\n    except AttributeError:\n        return False\n    if not (hasattr(pkg_version, \"vstring\") and hasattr(pkg_version, \"version\")):\n        # this is mock by sphinx, so it shall return True ro generate all summaries\n        return True\n    return op(pkg_version, LooseVersion(version))\n\n\n_TORCH_LOWER_1_4 = LooseVersion(torch.__version__) < LooseVersion(\"1.4.0\")\n_TORCH_LOWER_1_5 = LooseVersion(torch.__version__) < LooseVersion(\"1.5.0\")\n_TORCH_LOWER_1_6 = LooseVersion(torch.__version__) < LooseVersion(\"1.6.0\")\n", "path": "torchmetrics/utilities/imports.py"}, {"content": "from torchmetrics.utilities.imports import _module_available\n\n_PL_AVAILABLE = _module_available('pytorch_lightning')\n", "path": "integrations/__init__.py"}]}