prompt: 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()
  
  ```
  
golden_diff: 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")
  
verification_info: {"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"}]}