diff --git a/.azure/gpu-integrations.yml b/.azure/gpu-integrations.yml index 8478ab6d3e0..0073a3d5e00 100644 --- a/.azure/gpu-integrations.yml +++ b/.azure/gpu-integrations.yml @@ -17,9 +17,9 @@ jobs: - job: integrate_GPU strategy: matrix: - "torch | 1.x": - docker-image: "pytorchlightning/torchmetrics:ubuntu22.04-cuda11.8.0-py3.9-torch1.13" - torch-ver: "1.13" + "torch | 2.0": + docker-image: "pytorch/pytorch:2.0.1-cuda11.7-cudnn8-runtime" + torch-ver: "2.0" requires: "oldest" "torch | 2.x": docker-image: "pytorch/pytorch:2.4.0-cuda12.1-cudnn9-runtime" diff --git a/.azure/gpu-unittests.yml b/.azure/gpu-unittests.yml index 78dc6beee86..ecad60814f9 100644 --- a/.azure/gpu-unittests.yml +++ b/.azure/gpu-unittests.yml @@ -24,13 +24,10 @@ jobs: - job: unitest_GPU strategy: matrix: - "PyTorch | 1.10 oldest": + "PyTorch | 2.0 oldest": # Torch does not have build wheels with old Torch versions for newer CUDA - docker-image: "ubuntu20.04-cuda11.3.1-py3.9-torch1.10" - torch-ver: "1.10" - "PyTorch | 1.X LTS": - docker-image: "ubuntu22.04-cuda11.8.0-py3.9-torch1.13" - torch-ver: "1.13" + docker-image: "ubuntu22.04-cuda11.8.0-py3.10-torch2.0" + torch-ver: "2.0" "PyTorch | 2.X stable": docker-image: "ubuntu22.04-cuda12.1.1-py3.11-torch2.4" torch-ver: "2.4" @@ -123,7 +120,7 @@ jobs: - bash: | python .github/assistant.py set-oldest-versions - condition: eq(variables['torch-ver'], '1.10') + condition: eq(variables['torch-ver'], '2.0') displayName: "Setting oldest versions" - bash: | @@ -191,7 +188,7 @@ jobs: workingDirectory: "tests/" # skip for PR if there is nothing to test, note that outside PR there is default 'unittests' condition: and(succeeded(), ne(variables['TEST_DIRS'], '')) - timeoutInMinutes: "90" + timeoutInMinutes: "95" displayName: "UnitTesting common" - bash: | @@ -203,7 +200,7 @@ jobs: workingDirectory: "tests/" # skip for PR if there is nothing to test, note that outside PR there is default 'unittests' condition: and(succeeded(), ne(variables['TEST_DIRS'], '')) - timeoutInMinutes: "90" + timeoutInMinutes: "95" displayName: "UnitTesting DDP" - bash: | diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index 0647a865ebb..ac9f2519d5b 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -34,10 +34,6 @@ jobs: os: ["ubuntu-20.04"] python-version: ["3.9"] pytorch-version: - - "1.10.2" - - "1.11.0" - - "1.12.1" - - "1.13.1" - "2.0.1" - "2.1.2" - "2.2.2" @@ -45,18 +41,15 @@ jobs: - "2.4.0" include: # cover additional python and PT combinations - - { os: "ubuntu-22.04", python-version: "3.8", pytorch-version: "1.13.1" } - { os: "ubuntu-22.04", python-version: "3.10", pytorch-version: "2.0.1" } - { os: "ubuntu-22.04", python-version: "3.10", pytorch-version: "2.2.2" } - { os: "ubuntu-22.04", python-version: "3.11", pytorch-version: "2.3.1" } # standard mac machine, not the M1 - - { os: "macOS-13", python-version: "3.8", pytorch-version: "1.13.1" } - { os: "macOS-13", python-version: "3.10", pytorch-version: "2.0.1" } # using the ARM based M1 machine - { os: "macOS-14", python-version: "3.10", pytorch-version: "2.0.1" } - { os: "macOS-14", python-version: "3.11", pytorch-version: "2.4.0" } # some windows - - { os: "windows-2022", python-version: "3.8", pytorch-version: "1.13.1" } - { os: "windows-2022", python-version: "3.10", pytorch-version: "2.0.1" } - { os: "windows-2022", python-version: "3.11", pytorch-version: "2.4.0" } # Future released version diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 2c17c5ee68d..7bd5364e6f6 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -66,9 +66,6 @@ jobs: include: # These are the base images for PL release docker images, # so include at least all the combinations in release-dockers.yml. - - { python: "3.9", pytorch: "1.10", cuda: "11.3.1", ubuntu: "20.04" } - #- { python: "3.9", pytorch: "1.11", cuda: "11.8.0", ubuntu: "22.04" } - - { python: "3.9", pytorch: "1.13", cuda: "11.8.0", ubuntu: "22.04" } - { python: "3.10", pytorch: "2.2", cuda: "12.1.1", ubuntu: "22.04" } - { python: "3.11", pytorch: "2.2", cuda: "12.1.1", ubuntu: "22.04" } - { python: "3.11", pytorch: "2.3", cuda: "12.1.1", ubuntu: "22.04" } diff --git a/CHANGELOG.md b/CHANGELOG.md index f8143e1e07e..e439d426ae2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed -- +- Changed minimum supported Pytorch version to 2.0 ([#2671](https://github.com/Lightning-AI/torchmetrics/pull/2671)) ### Fixed diff --git a/requirements/_tests.txt b/requirements/_tests.txt index a2910fdc2d2..889b468659f 100644 --- a/requirements/_tests.txt +++ b/requirements/_tests.txt @@ -1,6 +1,7 @@ # NOTE: the upper bound for the package version is only set for CI stability, and it is dropped while installing this package # in case you want to preserve/enforce restrictions on the latest compatible version, add "strict" as an in-line comment +codecov ==2.1.13 coverage ==7.6.* codecov ==2.1.13 pytest ==8.3.* diff --git a/requirements/audio.txt b/requirements/audio.txt index 0e443bfc4c0..de68ffb798d 100644 --- a/requirements/audio.txt +++ b/requirements/audio.txt @@ -4,8 +4,8 @@ # this need to be the same as used inside speechmetrics pesq >=0.0.4, <0.0.5 pystoi >=0.4.0, <0.5.0 -torchaudio >=0.10.0, <2.5.0 +torchaudio >=2.0.1, <2.5.0 gammatone >=1.0.0, <1.1.0 -librosa >=0.9.0, <0.11.0 +librosa >=0.10.0, <0.11.0 onnxruntime >=1.12.0, <1.20 # installing onnxruntime_gpu-gpu failed on macos requests >=2.19.0, <2.33.0 diff --git a/requirements/base.txt b/requirements/base.txt index 0140f7a5519..b4a98163123 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -3,6 +3,6 @@ numpy >1.20.0, <2.0 # strict, for compatibility reasons packaging >17.1 -torch >=1.10.0, <2.5.0 +torch >=2.0.0, <2.5.0 typing-extensions; python_version < '3.9' lightning-utilities >=0.8.0, <0.12.0 diff --git a/requirements/detection.txt b/requirements/detection.txt index cc65884fa16..cffdfb02aa1 100644 --- a/requirements/detection.txt +++ b/requirements/detection.txt @@ -1,5 +1,5 @@ # NOTE: the upper bound for the package version is only set for CI stability, and it is dropped while installing this package # in case you want to preserve/enforce restrictions on the latest compatible version, add "strict" as an in-line comment -torchvision >=0.8, <0.20.0 +torchvision >=0.15.1, <0.20.0 pycocotools >2.0.0, <2.1.0 diff --git a/requirements/image.txt b/requirements/image.txt index 70cd2ee21a2..62824c4a98b 100644 --- a/requirements/image.txt +++ b/requirements/image.txt @@ -2,5 +2,5 @@ # in case you want to preserve/enforce restrictions on the latest compatible version, add "strict" as an in-line comment scipy >1.0.0, <1.15.0 -torchvision >=0.8, <0.20.0 +torchvision >=0.15.1, <0.20.0 torch-fidelity <=0.4.0 # bumping to allow install version from master, now used in testing diff --git a/src/torchmetrics/audio/__init__.py b/src/torchmetrics/audio/__init__.py index 6d21902b13e..14b987a7113 100644 --- a/src/torchmetrics/audio/__init__.py +++ b/src/torchmetrics/audio/__init__.py @@ -28,10 +28,17 @@ _ONNXRUNTIME_AVAILABLE, _PESQ_AVAILABLE, _PYSTOI_AVAILABLE, + _SCIPI_AVAILABLE, _TORCHAUDIO_AVAILABLE, - _TORCHAUDIO_GREATER_EQUAL_0_10, ) +if _SCIPI_AVAILABLE: + import scipy.signal + + # back compatibility patch due to SMRMpy using scipy.signal.hamming + if not hasattr(scipy.signal, "hamming"): + scipy.signal.hamming = scipy.signal.windows.hamming + __all__ = [ "PermutationInvariantTraining", "ScaleInvariantSignalDistortionRatio", @@ -52,7 +59,7 @@ __all__ += ["ShortTimeObjectiveIntelligibility"] -if _GAMMATONE_AVAILABLE and _TORCHAUDIO_AVAILABLE and _TORCHAUDIO_GREATER_EQUAL_0_10: +if _GAMMATONE_AVAILABLE and _TORCHAUDIO_AVAILABLE: from torchmetrics.audio.srmr import SpeechReverberationModulationEnergyRatio __all__ += ["SpeechReverberationModulationEnergyRatio"] diff --git a/src/torchmetrics/audio/srmr.py b/src/torchmetrics/audio/srmr.py index 62a882e7ccc..0ced6d6f24f 100644 --- a/src/torchmetrics/audio/srmr.py +++ b/src/torchmetrics/audio/srmr.py @@ -24,11 +24,10 @@ _GAMMATONE_AVAILABLE, _MATPLOTLIB_AVAILABLE, _TORCHAUDIO_AVAILABLE, - _TORCHAUDIO_GREATER_EQUAL_0_10, ) from torchmetrics.utilities.plot import _AX_TYPE, _PLOT_OUT_TYPE -if not all([_GAMMATONE_AVAILABLE, _TORCHAUDIO_AVAILABLE, _TORCHAUDIO_GREATER_EQUAL_0_10]): +if not all([_GAMMATONE_AVAILABLE, _TORCHAUDIO_AVAILABLE]): __doctest_skip__ = ["SpeechReverberationModulationEnergyRatio", "SpeechReverberationModulationEnergyRatio.plot"] elif not _MATPLOTLIB_AVAILABLE: __doctest_skip__ = ["SpeechReverberationModulationEnergyRatio.plot"] @@ -105,7 +104,7 @@ def __init__( **kwargs: Any, ) -> None: super().__init__(**kwargs) - if not _TORCHAUDIO_AVAILABLE or not _TORCHAUDIO_GREATER_EQUAL_0_10 or not _GAMMATONE_AVAILABLE: + if not _TORCHAUDIO_AVAILABLE or not _GAMMATONE_AVAILABLE: raise ModuleNotFoundError( "speech_reverberation_modulation_energy_ratio requires you to have `gammatone` and" " `torchaudio>=0.10` installed. Either install as ``pip install torchmetrics[audio]`` or " diff --git a/src/torchmetrics/detection/__init__.py b/src/torchmetrics/detection/__init__.py index 5fd60cf4e4d..7932d4b33b8 100644 --- a/src/torchmetrics/detection/__init__.py +++ b/src/torchmetrics/detection/__init__.py @@ -12,22 +12,21 @@ # See the License for the specific language governing permissions and # limitations under the License. from torchmetrics.detection.panoptic_qualities import ModifiedPanopticQuality, PanopticQuality -from torchmetrics.utilities.imports import ( - _TORCHVISION_GREATER_EQUAL_0_8, - _TORCHVISION_GREATER_EQUAL_0_13, -) +from torchmetrics.utilities.imports import _TORCHVISION_AVAILABLE __all__ = ["ModifiedPanopticQuality", "PanopticQuality"] -if _TORCHVISION_GREATER_EQUAL_0_8: +if _TORCHVISION_AVAILABLE: + from torchmetrics.detection.ciou import CompleteIntersectionOverUnion + from torchmetrics.detection.diou import DistanceIntersectionOverUnion from torchmetrics.detection.giou import GeneralizedIntersectionOverUnion from torchmetrics.detection.iou import IntersectionOverUnion from torchmetrics.detection.mean_ap import MeanAveragePrecision - __all__ += ["MeanAveragePrecision", "GeneralizedIntersectionOverUnion", "IntersectionOverUnion"] - -if _TORCHVISION_GREATER_EQUAL_0_13: - from torchmetrics.detection.ciou import CompleteIntersectionOverUnion - from torchmetrics.detection.diou import DistanceIntersectionOverUnion - - __all__ += ["CompleteIntersectionOverUnion", "DistanceIntersectionOverUnion"] + __all__ += [ + "MeanAveragePrecision", + "GeneralizedIntersectionOverUnion", + "IntersectionOverUnion", + "CompleteIntersectionOverUnion", + "DistanceIntersectionOverUnion", + ] diff --git a/src/torchmetrics/detection/_deprecated.py b/src/torchmetrics/detection/_deprecated.py index 898f341bd62..c162c751554 100644 --- a/src/torchmetrics/detection/_deprecated.py +++ b/src/torchmetrics/detection/_deprecated.py @@ -1,17 +1,8 @@ from typing import Any, Collection from torchmetrics.detection import ModifiedPanopticQuality, PanopticQuality -from torchmetrics.utilities.imports import _TORCH_GREATER_EQUAL_1_12 from torchmetrics.utilities.prints import _deprecated_root_import_class -if not _TORCH_GREATER_EQUAL_1_12: - __doctest_skip__ = [ - "_PanopticQuality", - "_PanopticQuality.*", - "_ModifiedPanopticQuality", - "_ModifiedPanopticQuality.*", - ] - class _ModifiedPanopticQuality(ModifiedPanopticQuality): """Wrapper for deprecated import. diff --git a/src/torchmetrics/detection/_mean_ap.py b/src/torchmetrics/detection/_mean_ap.py index fd342608360..4de1f8fe762 100644 --- a/src/torchmetrics/detection/_mean_ap.py +++ b/src/torchmetrics/detection/_mean_ap.py @@ -22,13 +22,13 @@ from torchmetrics.detection.helpers import _fix_empty_tensors, _input_validator from torchmetrics.metric import Metric from torchmetrics.utilities.data import _cumsum -from torchmetrics.utilities.imports import _MATPLOTLIB_AVAILABLE, _PYCOCOTOOLS_AVAILABLE, _TORCHVISION_GREATER_EQUAL_0_8 +from torchmetrics.utilities.imports import _MATPLOTLIB_AVAILABLE, _PYCOCOTOOLS_AVAILABLE, _TORCHVISION_AVAILABLE from torchmetrics.utilities.plot import _AX_TYPE, _PLOT_OUT_TYPE if not _MATPLOTLIB_AVAILABLE: __doctest_skip__ = ["MeanAveragePrecision.plot"] -if not _TORCHVISION_GREATER_EQUAL_0_8 or not _PYCOCOTOOLS_AVAILABLE: +if not _TORCHVISION_AVAILABLE or not _PYCOCOTOOLS_AVAILABLE: __doctest_skip__ = ["MeanAveragePrecision.plot", "MeanAveragePrecision"] log = logging.getLogger(__name__) @@ -327,10 +327,10 @@ def __init__( "`MAP` metric requires that `pycocotools` installed." " Please install with `pip install pycocotools` or `pip install torchmetrics[detection]`" ) - if not _TORCHVISION_GREATER_EQUAL_0_8: + if not _TORCHVISION_AVAILABLE: raise ModuleNotFoundError( - "`MeanAveragePrecision` metric requires that `torchvision` version 0.8.0 or newer is installed." - " Please install with `pip install torchvision>=0.8` or `pip install torchmetrics[detection]`." + "`MeanAveragePrecision` metric requires that `torchvision` is installed." + " Please install with `pip install torchmetrics[detection]`." ) allowed_box_formats = ("xyxy", "xywh", "cxcywh") diff --git a/src/torchmetrics/detection/ciou.py b/src/torchmetrics/detection/ciou.py index 0e5b304c44e..b6174c3b60c 100644 --- a/src/torchmetrics/detection/ciou.py +++ b/src/torchmetrics/detection/ciou.py @@ -17,10 +17,10 @@ from torchmetrics.detection.iou import IntersectionOverUnion from torchmetrics.functional.detection.ciou import _ciou_compute, _ciou_update -from torchmetrics.utilities.imports import _MATPLOTLIB_AVAILABLE, _TORCHVISION_GREATER_EQUAL_0_13 +from torchmetrics.utilities.imports import _MATPLOTLIB_AVAILABLE, _TORCHVISION_AVAILABLE from torchmetrics.utilities.plot import _AX_TYPE, _PLOT_OUT_TYPE -if not _TORCHVISION_GREATER_EQUAL_0_13: +if not _TORCHVISION_AVAILABLE: __doctest_skip__ = ["CompleteIntersectionOverUnion", "CompleteIntersectionOverUnion.plot"] elif not _MATPLOTLIB_AVAILABLE: __doctest_skip__ = ["CompleteIntersectionOverUnion.plot"] @@ -110,10 +110,10 @@ def __init__( respect_labels: bool = True, **kwargs: Any, ) -> None: - if not _TORCHVISION_GREATER_EQUAL_0_13: + if not _TORCHVISION_AVAILABLE: raise ModuleNotFoundError( - f"Metric `{self._iou_type.upper()}` requires that `torchvision` version 0.13.0 or newer is installed." - " Please install with `pip install torchvision>=0.13` or `pip install torchmetrics[detection]`." + f"Metric `{self._iou_type.upper()}` requires that `torchvision` is installed." + " Please install with `pip install torchmetrics[detection]`." ) super().__init__(box_format, iou_threshold, class_metrics, respect_labels, **kwargs) diff --git a/src/torchmetrics/detection/diou.py b/src/torchmetrics/detection/diou.py index 87fa0933d2b..7eb3780a112 100644 --- a/src/torchmetrics/detection/diou.py +++ b/src/torchmetrics/detection/diou.py @@ -17,10 +17,10 @@ from torchmetrics.detection.iou import IntersectionOverUnion from torchmetrics.functional.detection.diou import _diou_compute, _diou_update -from torchmetrics.utilities.imports import _MATPLOTLIB_AVAILABLE, _TORCHVISION_GREATER_EQUAL_0_13 +from torchmetrics.utilities.imports import _MATPLOTLIB_AVAILABLE, _TORCHVISION_AVAILABLE from torchmetrics.utilities.plot import _AX_TYPE, _PLOT_OUT_TYPE -if not _TORCHVISION_GREATER_EQUAL_0_13: +if not _TORCHVISION_AVAILABLE: __doctest_skip__ = ["DistanceIntersectionOverUnion", "DistanceIntersectionOverUnion.plot"] elif not _MATPLOTLIB_AVAILABLE: __doctest_skip__ = ["DistanceIntersectionOverUnion.plot"] @@ -110,10 +110,10 @@ def __init__( respect_labels: bool = True, **kwargs: Any, ) -> None: - if not _TORCHVISION_GREATER_EQUAL_0_13: + if not _TORCHVISION_AVAILABLE: raise ModuleNotFoundError( - f"Metric `{self._iou_type.upper()}` requires that `torchvision` version 0.13.0 or newer is installed." - " Please install with `pip install torchvision>=0.13` or `pip install torchmetrics[detection]`." + f"Metric `{self._iou_type.upper()}` requires that `torchvision` is installed." + " Please install with `pip install torchmetrics[detection]`." ) super().__init__(box_format, iou_threshold, class_metrics, respect_labels, **kwargs) diff --git a/src/torchmetrics/detection/giou.py b/src/torchmetrics/detection/giou.py index 0d4156561c4..d024adad817 100644 --- a/src/torchmetrics/detection/giou.py +++ b/src/torchmetrics/detection/giou.py @@ -17,10 +17,10 @@ from torchmetrics.detection.iou import IntersectionOverUnion from torchmetrics.functional.detection.giou import _giou_compute, _giou_update -from torchmetrics.utilities.imports import _MATPLOTLIB_AVAILABLE, _TORCHVISION_GREATER_EQUAL_0_8 +from torchmetrics.utilities.imports import _MATPLOTLIB_AVAILABLE, _TORCHVISION_AVAILABLE from torchmetrics.utilities.plot import _AX_TYPE, _PLOT_OUT_TYPE -if not _TORCHVISION_GREATER_EQUAL_0_8: +if not _TORCHVISION_AVAILABLE: __doctest_skip__ = ["GeneralizedIntersectionOverUnion", "GeneralizedIntersectionOverUnion.plot"] elif not _MATPLOTLIB_AVAILABLE: __doctest_skip__ = ["GeneralizedIntersectionOverUnion.plot"] diff --git a/src/torchmetrics/detection/iou.py b/src/torchmetrics/detection/iou.py index e809b27ce6a..ca4178d35ee 100644 --- a/src/torchmetrics/detection/iou.py +++ b/src/torchmetrics/detection/iou.py @@ -20,10 +20,10 @@ from torchmetrics.functional.detection.iou import _iou_compute, _iou_update from torchmetrics.metric import Metric from torchmetrics.utilities.data import dim_zero_cat -from torchmetrics.utilities.imports import _MATPLOTLIB_AVAILABLE, _TORCHVISION_GREATER_EQUAL_0_8 +from torchmetrics.utilities.imports import _MATPLOTLIB_AVAILABLE, _TORCHVISION_AVAILABLE from torchmetrics.utilities.plot import _AX_TYPE, _PLOT_OUT_TYPE -if not _TORCHVISION_GREATER_EQUAL_0_8: +if not _TORCHVISION_AVAILABLE: __doctest_skip__ = ["IntersectionOverUnion", "IntersectionOverUnion.plot"] elif not _MATPLOTLIB_AVAILABLE: __doctest_skip__ = ["IntersectionOverUnion.plot"] @@ -146,10 +146,10 @@ def __init__( ) -> None: super().__init__(**kwargs) - if not _TORCHVISION_GREATER_EQUAL_0_8: + if not _TORCHVISION_AVAILABLE: raise ModuleNotFoundError( - f"Metric `{self._iou_type.upper()}` requires that `torchvision` version 0.8.0 or newer is installed." - " Please install with `pip install torchvision>=0.8` or `pip install torchmetrics[detection]`." + f"Metric `{self._iou_type.upper()}` requires that `torchvision` is installed." + " Please install with `pip install torchmetrics[detection]`." ) allowed_box_formats = ("xyxy", "xywh", "cxcywh") diff --git a/src/torchmetrics/detection/mean_ap.py b/src/torchmetrics/detection/mean_ap.py index 948fa554348..f7aa6eb0276 100644 --- a/src/torchmetrics/detection/mean_ap.py +++ b/src/torchmetrics/detection/mean_ap.py @@ -31,14 +31,14 @@ _FASTER_COCO_EVAL_AVAILABLE, _MATPLOTLIB_AVAILABLE, _PYCOCOTOOLS_AVAILABLE, - _TORCHVISION_GREATER_EQUAL_0_8, + _TORCHVISION_AVAILABLE, ) from torchmetrics.utilities.plot import _AX_TYPE, _PLOT_OUT_TYPE if not _MATPLOTLIB_AVAILABLE: __doctest_skip__ = ["MeanAveragePrecision.plot"] -if not _TORCHVISION_GREATER_EQUAL_0_8 or not (_PYCOCOTOOLS_AVAILABLE or _FASTER_COCO_EVAL_AVAILABLE): +if not (_PYCOCOTOOLS_AVAILABLE or _FASTER_COCO_EVAL_AVAILABLE): __doctest_skip__ = [ "MeanAveragePrecision.plot", "MeanAveragePrecision", @@ -390,10 +390,10 @@ def __init__( " Please install with `pip install pycocotools` or `pip install faster-coco-eval` or" " `pip install torchmetrics[detection]`." ) - if not _TORCHVISION_GREATER_EQUAL_0_8: + if not _TORCHVISION_AVAILABLE: raise ModuleNotFoundError( - "`MeanAveragePrecision` metric requires that `torchvision` version 0.8.0 or newer is installed." - " Please install with `pip install torchvision>=0.8` or `pip install torchmetrics[detection]`." + f"Metric `{self._iou_type.upper()}` requires that `torchvision` is installed." + " Please install with `pip install torchmetrics[detection]`." ) allowed_box_formats = ("xyxy", "xywh", "cxcywh") diff --git a/src/torchmetrics/detection/panoptic_qualities.py b/src/torchmetrics/detection/panoptic_qualities.py index 50b7c4c5594..b4629be8e69 100644 --- a/src/torchmetrics/detection/panoptic_qualities.py +++ b/src/torchmetrics/detection/panoptic_qualities.py @@ -26,17 +26,13 @@ _validate_inputs, ) from torchmetrics.metric import Metric -from torchmetrics.utilities.imports import _MATPLOTLIB_AVAILABLE, _TORCH_GREATER_EQUAL_1_12 +from torchmetrics.utilities.imports import _MATPLOTLIB_AVAILABLE from torchmetrics.utilities.plot import _AX_TYPE, _PLOT_OUT_TYPE if not _MATPLOTLIB_AVAILABLE: __doctest_skip__ = ["PanopticQuality.plot", "ModifiedPanopticQuality.plot"] -if not _TORCH_GREATER_EQUAL_1_12: - __doctest_skip__ = ["PanopticQuality", "PanopticQuality.*", "ModifiedPanopticQuality", "ModifiedPanopticQuality.*"] - - class PanopticQuality(Metric): r"""Compute the `Panoptic Quality`_ for panoptic segmentations. @@ -166,9 +162,6 @@ def __init__( **kwargs: Any, ) -> None: super().__init__(**kwargs) - if not _TORCH_GREATER_EQUAL_1_12: - raise RuntimeError("Panoptic Quality metric requires PyTorch 1.12 or later") - things, stuffs = _parse_categories(things, stuffs) self.things = things self.stuffs = stuffs diff --git a/src/torchmetrics/functional/audio/__init__.py b/src/torchmetrics/functional/audio/__init__.py index c8a8b5a4bcc..ac228cf671a 100644 --- a/src/torchmetrics/functional/audio/__init__.py +++ b/src/torchmetrics/functional/audio/__init__.py @@ -28,10 +28,17 @@ _ONNXRUNTIME_AVAILABLE, _PESQ_AVAILABLE, _PYSTOI_AVAILABLE, + _SCIPI_AVAILABLE, _TORCHAUDIO_AVAILABLE, - _TORCHAUDIO_GREATER_EQUAL_0_10, ) +if _SCIPI_AVAILABLE: + import scipy.signal + + # back compatibility patch due to SMRMpy using scipy.signal.hamming + if not hasattr(scipy.signal, "hamming"): + scipy.signal.hamming = scipy.signal.windows.hamming + __all__ = [ "permutation_invariant_training", "pit_permutate", @@ -53,7 +60,7 @@ __all__ += ["short_time_objective_intelligibility"] -if _GAMMATONE_AVAILABLE and _TORCHAUDIO_AVAILABLE and _TORCHAUDIO_GREATER_EQUAL_0_10: +if _GAMMATONE_AVAILABLE and _TORCHAUDIO_AVAILABLE: from torchmetrics.functional.audio.srmr import speech_reverberation_modulation_energy_ratio __all__ += ["speech_reverberation_modulation_energy_ratio"] diff --git a/src/torchmetrics/functional/audio/srmr.py b/src/torchmetrics/functional/audio/srmr.py index 79f710a6a31..d098366df6b 100644 --- a/src/torchmetrics/functional/audio/srmr.py +++ b/src/torchmetrics/functional/audio/srmr.py @@ -27,10 +27,9 @@ from torchmetrics.utilities.imports import ( _GAMMATONE_AVAILABLE, _TORCHAUDIO_AVAILABLE, - _TORCHAUDIO_GREATER_EQUAL_0_10, ) -if not _TORCHAUDIO_AVAILABLE or not _TORCHAUDIO_GREATER_EQUAL_0_10 or not _GAMMATONE_AVAILABLE: +if not _TORCHAUDIO_AVAILABLE or not _GAMMATONE_AVAILABLE: __doctest_skip__ = ["speech_reverberation_modulation_energy_ratio"] @@ -228,7 +227,7 @@ def speech_reverberation_modulation_energy_ratio( tensor([0.3191], dtype=torch.float64) """ - if not _TORCHAUDIO_AVAILABLE or not _TORCHAUDIO_GREATER_EQUAL_0_10 or not _GAMMATONE_AVAILABLE: + if not _TORCHAUDIO_AVAILABLE or not _GAMMATONE_AVAILABLE: raise ModuleNotFoundError( "speech_reverberation_modulation_energy_ratio requires you to have `gammatone` and" " `torchaudio>=0.10` installed. Either install as ``pip install torchmetrics[audio]`` or " diff --git a/src/torchmetrics/functional/detection/__init__.py b/src/torchmetrics/functional/detection/__init__.py index 8f818c7b2df..fab5ccb5f91 100644 --- a/src/torchmetrics/functional/detection/__init__.py +++ b/src/torchmetrics/functional/detection/__init__.py @@ -15,20 +15,19 @@ from torchmetrics.functional.detection.panoptic_qualities import modified_panoptic_quality, panoptic_quality from torchmetrics.utilities.imports import ( _TORCHVISION_AVAILABLE, - _TORCHVISION_GREATER_EQUAL_0_8, - _TORCHVISION_GREATER_EQUAL_0_13, ) __all__ = ["modified_panoptic_quality", "panoptic_quality"] -if _TORCHVISION_AVAILABLE and _TORCHVISION_GREATER_EQUAL_0_8: - from torchmetrics.functional.detection.giou import generalized_intersection_over_union - from torchmetrics.functional.detection.iou import intersection_over_union - - __all__ += ["generalized_intersection_over_union", "intersection_over_union"] - -if _TORCHVISION_AVAILABLE and _TORCHVISION_GREATER_EQUAL_0_13: +if _TORCHVISION_AVAILABLE: from torchmetrics.functional.detection.ciou import complete_intersection_over_union from torchmetrics.functional.detection.diou import distance_intersection_over_union + from torchmetrics.functional.detection.giou import generalized_intersection_over_union + from torchmetrics.functional.detection.iou import intersection_over_union - __all__ += ["complete_intersection_over_union", "distance_intersection_over_union"] + __all__ += [ + "generalized_intersection_over_union", + "intersection_over_union", + "complete_intersection_over_union", + "distance_intersection_over_union", + ] diff --git a/src/torchmetrics/functional/detection/_deprecated.py b/src/torchmetrics/functional/detection/_deprecated.py index b2500d34f0d..ce0e1ba6acf 100644 --- a/src/torchmetrics/functional/detection/_deprecated.py +++ b/src/torchmetrics/functional/detection/_deprecated.py @@ -3,12 +3,8 @@ from torch import Tensor from torchmetrics.functional.detection.panoptic_qualities import modified_panoptic_quality, panoptic_quality -from torchmetrics.utilities.imports import _TORCH_GREATER_EQUAL_1_12 from torchmetrics.utilities.prints import _deprecated_root_import_func -if not _TORCH_GREATER_EQUAL_1_12: - __doctest_skip__ = ["_panoptic_quality", "_modified_panoptic_quality"] - def _modified_panoptic_quality( preds: Tensor, diff --git a/src/torchmetrics/functional/detection/ciou.py b/src/torchmetrics/functional/detection/ciou.py index 9669029ba73..650651b2e4f 100644 --- a/src/torchmetrics/functional/detection/ciou.py +++ b/src/torchmetrics/functional/detection/ciou.py @@ -15,9 +15,9 @@ import torch -from torchmetrics.utilities.imports import _TORCHVISION_GREATER_EQUAL_0_13 +from torchmetrics.utilities.imports import _TORCHVISION_AVAILABLE -if not _TORCHVISION_GREATER_EQUAL_0_13: +if not _TORCHVISION_AVAILABLE: __doctest_skip__ = ["complete_intersection_over_union"] @@ -113,11 +113,10 @@ def complete_intersection_over_union( [-0.3971, -0.1543, 0.5606]]) """ - if not _TORCHVISION_GREATER_EQUAL_0_13: + if not _TORCHVISION_AVAILABLE: raise ModuleNotFoundError( - f"`{complete_intersection_over_union.__name__}` requires that `torchvision` version 0.13.0 or newer" - " is installed." - " Please install with `pip install torchvision>=0.13` or `pip install torchmetrics[detection]`." + f"`{complete_intersection_over_union.__name__}` requires that `torchvision` is installed." + " Please install with `pip install torchmetrics[detection]`." ) iou = _ciou_update(preds, target, iou_threshold, replacement_val) return _ciou_compute(iou, aggregate) diff --git a/src/torchmetrics/functional/detection/diou.py b/src/torchmetrics/functional/detection/diou.py index 13fb0071fed..7a9a3d907a9 100644 --- a/src/torchmetrics/functional/detection/diou.py +++ b/src/torchmetrics/functional/detection/diou.py @@ -15,9 +15,9 @@ import torch -from torchmetrics.utilities.imports import _TORCHVISION_GREATER_EQUAL_0_13 +from torchmetrics.utilities.imports import _TORCHVISION_AVAILABLE -if not _TORCHVISION_GREATER_EQUAL_0_13: +if not _TORCHVISION_AVAILABLE: __doctest_skip__ = ["distance_intersection_over_union"] @@ -113,11 +113,10 @@ def distance_intersection_over_union( [-0.3971, -0.1510, 0.5609]]) """ - if not _TORCHVISION_GREATER_EQUAL_0_13: + if not _TORCHVISION_AVAILABLE: raise ModuleNotFoundError( - f"`{distance_intersection_over_union.__name__}` requires that `torchvision` version 0.13.0 or newer" - " is installed." - " Please install with `pip install torchvision>=0.13` or `pip install torchmetrics[detection]`." + f"`{distance_intersection_over_union.__name__}` requires that `torchvision` is installed." + " Please install with `pip install torchmetrics[detection]`." ) iou = _diou_update(preds, target, iou_threshold, replacement_val) return _diou_compute(iou, aggregate) diff --git a/src/torchmetrics/functional/detection/giou.py b/src/torchmetrics/functional/detection/giou.py index cc39f813b41..feae12d3011 100644 --- a/src/torchmetrics/functional/detection/giou.py +++ b/src/torchmetrics/functional/detection/giou.py @@ -15,9 +15,9 @@ import torch -from torchmetrics.utilities.imports import _TORCHVISION_GREATER_EQUAL_0_8 +from torchmetrics.utilities.imports import _TORCHVISION_AVAILABLE -if not _TORCHVISION_GREATER_EQUAL_0_8: +if not _TORCHVISION_AVAILABLE: __doctest_skip__ = ["generalized_intersection_over_union"] @@ -113,11 +113,10 @@ def generalized_intersection_over_union( [-0.6024, -0.4021, 0.5345]]) """ - if not _TORCHVISION_GREATER_EQUAL_0_8: + if not _TORCHVISION_AVAILABLE: raise ModuleNotFoundError( - f"`{generalized_intersection_over_union.__name__}` requires that `torchvision` version 0.8.0 or newer" - " is installed." - " Please install with `pip install torchvision>=0.8` or `pip install torchmetrics[detection]`." + f"`{generalized_intersection_over_union.__name__}` requires that `torchvision` is installed." + " Please install with `pip install torchmetrics[detection]`." ) iou = _giou_update(preds, target, iou_threshold, replacement_val) return _giou_compute(iou, aggregate) diff --git a/src/torchmetrics/functional/detection/iou.py b/src/torchmetrics/functional/detection/iou.py index 3d3cef26bb2..249b30dd2d9 100644 --- a/src/torchmetrics/functional/detection/iou.py +++ b/src/torchmetrics/functional/detection/iou.py @@ -15,9 +15,9 @@ import torch -from torchmetrics.utilities.imports import _TORCHVISION_GREATER_EQUAL_0_8 +from torchmetrics.utilities.imports import _TORCHVISION_AVAILABLE -if not _TORCHVISION_GREATER_EQUAL_0_8: +if not _TORCHVISION_AVAILABLE: __doctest_skip__ = ["intersection_over_union"] @@ -114,10 +114,10 @@ def intersection_over_union( [0.0000, 0.0000, 0.5654]]) """ - if not _TORCHVISION_GREATER_EQUAL_0_8: + if not _TORCHVISION_AVAILABLE: raise ModuleNotFoundError( - f"`{intersection_over_union.__name__}` requires that `torchvision` version 0.8.0 or newer is installed." - " Please install with `pip install torchvision>=0.8` or `pip install torchmetrics[detection]`." + f"`{intersection_over_union.__name__}` requires that `torchvision` is installed." + " Please install with `pip install torchmetrics[detection]`." ) iou = _iou_update(preds, target, iou_threshold, replacement_val) return _iou_compute(iou, aggregate) diff --git a/src/torchmetrics/functional/detection/panoptic_qualities.py b/src/torchmetrics/functional/detection/panoptic_qualities.py index 2de9fa09bfa..019d243f0ba 100644 --- a/src/torchmetrics/functional/detection/panoptic_qualities.py +++ b/src/torchmetrics/functional/detection/panoptic_qualities.py @@ -25,10 +25,6 @@ _prepocess_inputs, _validate_inputs, ) -from torchmetrics.utilities.imports import _TORCH_GREATER_EQUAL_1_12 - -if not _TORCH_GREATER_EQUAL_1_12: - __doctest_skip__ = ["panoptic_quality", "modified_panoptic_quality"] def panoptic_quality( @@ -152,9 +148,6 @@ def panoptic_quality( [1.0000, 1.0000, 1.0000]], dtype=torch.float64) """ - if not _TORCH_GREATER_EQUAL_1_12: - raise RuntimeError("Panoptic Quality metric requires PyTorch 1.12 or later") - things, stuffs = _parse_categories(things, stuffs) _validate_inputs(preds, target) void_color = _get_void_color(things, stuffs) diff --git a/src/torchmetrics/functional/image/lpips.py b/src/torchmetrics/functional/image/lpips.py index 0ab3a84ced0..c557f61ead1 100644 --- a/src/torchmetrics/functional/image/lpips.py +++ b/src/torchmetrics/functional/image/lpips.py @@ -30,7 +30,7 @@ from torch import Tensor, nn from typing_extensions import Literal -from torchmetrics.utilities.imports import _TORCHVISION_AVAILABLE, _TORCHVISION_GREATER_EQUAL_0_13 +from torchmetrics.utilities.imports import _TORCHVISION_AVAILABLE _weight_map = { "squeezenet1_1": "SqueezeNet1_1_Weights", @@ -52,13 +52,11 @@ def _get_net(net: str, pretrained: bool) -> nn.modules.container.Sequential: """ from torchvision import models as tv - if _TORCHVISION_GREATER_EQUAL_0_13: + if _TORCHVISION_AVAILABLE: if pretrained: pretrained_features = getattr(tv, net)(weights=getattr(tv, _weight_map[net]).IMAGENET1K_V1).features else: pretrained_features = getattr(tv, net)(weights=None).features - else: - pretrained_features = getattr(tv, net)(pretrained=pretrained).features return pretrained_features diff --git a/src/torchmetrics/image/perceptual_path_length.py b/src/torchmetrics/image/perceptual_path_length.py index b2255941250..4c312404934 100644 --- a/src/torchmetrics/image/perceptual_path_length.py +++ b/src/torchmetrics/image/perceptual_path_length.py @@ -23,9 +23,9 @@ perceptual_path_length, ) from torchmetrics.metric import Metric -from torchmetrics.utilities.imports import _TORCH_GREATER_EQUAL_2_0, _TORCHVISION_AVAILABLE +from torchmetrics.utilities.imports import _TORCHVISION_AVAILABLE -if not _TORCHVISION_AVAILABLE or not _TORCH_GREATER_EQUAL_2_0: +if not _TORCHVISION_AVAILABLE: __doctest_skip__ = ["PerceptualPathLength"] diff --git a/src/torchmetrics/utilities/data.py b/src/torchmetrics/utilities/data.py index 2a6f7882d60..1a68e655c33 100644 --- a/src/torchmetrics/utilities/data.py +++ b/src/torchmetrics/utilities/data.py @@ -19,7 +19,7 @@ from torch import Tensor from torchmetrics.utilities.exceptions import TorchMetricsUserWarning -from torchmetrics.utilities.imports import _TORCH_GREATER_EQUAL_1_12, _TORCH_GREATER_EQUAL_1_13, _XLA_AVAILABLE +from torchmetrics.utilities.imports import _XLA_AVAILABLE from torchmetrics.utilities.prints import rank_zero_warn METRIC_EPS = 1e-6 @@ -115,8 +115,6 @@ def to_onehot( def _top_k_with_half_precision_support(x: Tensor, k: int = 1, dim: int = 1) -> Tensor: """torch.top_k does not support half precision on CPU.""" if x.dtype == torch.half and not x.is_cuda: - if not _TORCH_GREATER_EQUAL_1_13: - raise RuntimeError("Half precision (torch.float16) is not supported on CPU for PyTorch < 1.13.") idx = torch.argsort(x, dim=dim, stable=True).flip(dim) return idx.narrow(dim, 0, k) return x.topk(k=k, dim=dim).indices @@ -200,7 +198,7 @@ def _bincount(x: Tensor, minlength: Optional[int] = None) -> Tensor: if minlength is None: minlength = len(torch.unique(x)) - if torch.are_deterministic_algorithms_enabled() or _XLA_AVAILABLE or _TORCH_GREATER_EQUAL_1_12 and x.is_mps: + if torch.are_deterministic_algorithms_enabled() or _XLA_AVAILABLE and x.is_mps: mesh = torch.arange(minlength, device=x.device).repeat(len(x), 1) return torch.eq(x.reshape(-1, 1), mesh).sum(dim=0) diff --git a/src/torchmetrics/utilities/imports.py b/src/torchmetrics/utilities/imports.py index 10affebf579..5f6fb7001a5 100644 --- a/src/torchmetrics/utilities/imports.py +++ b/src/torchmetrics/utilities/imports.py @@ -19,11 +19,6 @@ from lightning_utilities.core.imports import RequirementCache _PYTHON_VERSION = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}" -_TORCH_LOWER_2_0 = RequirementCache("torch<2.0.0") -_TORCH_GREATER_EQUAL_1_11 = RequirementCache("torch>=1.11.0") -_TORCH_GREATER_EQUAL_1_12 = RequirementCache("torch>=1.12.0") -_TORCH_GREATER_EQUAL_1_13 = RequirementCache("torch>=1.13.0") -_TORCH_GREATER_EQUAL_2_0 = RequirementCache("torch>=2.0.0") _TORCH_GREATER_EQUAL_2_1 = RequirementCache("torch>=2.1.0") _TORCH_GREATER_EQUAL_2_2 = RequirementCache("torch>=2.2.0") _TORCHMETRICS_GREATER_EQUAL_1_6 = RequirementCache("torchmetrics>=1.7.0") @@ -37,8 +32,6 @@ _LPIPS_AVAILABLE = RequirementCache("lpips") _PYCOCOTOOLS_AVAILABLE = RequirementCache("pycocotools") _TORCHVISION_AVAILABLE = RequirementCache("torchvision") -_TORCHVISION_GREATER_EQUAL_0_8 = RequirementCache("torchvision>=0.8.0") -_TORCHVISION_GREATER_EQUAL_0_13 = RequirementCache("torchvision>=0.13.0") _TQDM_AVAILABLE = RequirementCache("tqdm") _TRANSFORMERS_AVAILABLE = RequirementCache("transformers") _TRANSFORMERS_GREATER_EQUAL_4_4 = RequirementCache("transformers>=4.4.0") @@ -46,7 +39,6 @@ _PESQ_AVAILABLE = RequirementCache("pesq") _GAMMATONE_AVAILABLE = RequirementCache("gammatone") _TORCHAUDIO_AVAILABLE = RequirementCache("torchaudio") -_TORCHAUDIO_GREATER_EQUAL_0_10 = RequirementCache("torchaudio>=0.10.0") _REGEX_AVAILABLE = RequirementCache("regex") _PYSTOI_AVAILABLE = RequirementCache("pystoi") _REQUESTS_AVAILABLE = RequirementCache("requests") diff --git a/tests/unittests/audio/test_sdr.py b/tests/unittests/audio/test_sdr.py index 61257588606..8d5a8c7ab8f 100644 --- a/tests/unittests/audio/test_sdr.py +++ b/tests/unittests/audio/test_sdr.py @@ -21,7 +21,6 @@ from torch import Tensor from torchmetrics.audio import SignalDistortionRatio from torchmetrics.functional import signal_distortion_ratio -from torchmetrics.utilities.imports import _TORCH_GREATER_EQUAL_1_11 from unittests import _Input from unittests._helpers import seed_all @@ -61,9 +60,6 @@ def _reference_sdr_batch( return sdr -@pytest.mark.skipif( # FIXME: figure out why tests leads to cuda errors on latest torch - _TORCH_GREATER_EQUAL_1_11 and torch.cuda.is_available(), reason="tests leads to cuda errors on latest torch" -) @pytest.mark.parametrize( "preds, target", [(inputs_1spk.preds, inputs_1spk.target), (inputs_2spk.preds, inputs_2spk.target)], @@ -137,12 +133,8 @@ def test_on_real_audio(): """Test that metric works on real audio signal.""" _, ref = wavfile.read(_SAMPLE_AUDIO_SPEECH) _, deg = wavfile.read(_SAMPLE_AUDIO_SPEECH_BAB_DB) - assert torch.allclose( - signal_distortion_ratio(torch.from_numpy(deg), torch.from_numpy(ref)).float(), - torch.tensor(0.2211), - rtol=0.0001, - atol=1e-4, - ) + sdr = signal_distortion_ratio(torch.from_numpy(deg), torch.from_numpy(ref)) + assert torch.allclose(sdr.float(), torch.tensor(0.2211), rtol=0.0001, atol=1e-4) def test_too_low_precision(): diff --git a/tests/unittests/audio/test_srmr.py b/tests/unittests/audio/test_srmr.py index 3b1b07862ce..e7370546478 100644 --- a/tests/unittests/audio/test_srmr.py +++ b/tests/unittests/audio/test_srmr.py @@ -20,7 +20,6 @@ from torch import Tensor from torchmetrics.audio.srmr import SpeechReverberationModulationEnergyRatio from torchmetrics.functional.audio.srmr import speech_reverberation_modulation_energy_ratio -from torchmetrics.utilities.imports import _TORCHAUDIO_GREATER_EQUAL_0_10 from unittests._helpers import seed_all from unittests._helpers.testers import MetricTester @@ -63,8 +62,6 @@ def update(self, preds: Tensor, target: Tensor) -> None: super().update(preds=preds) -# FIXME: bring compatibility with torchaudio 0.10+ -@pytest.mark.skipif(not _TORCHAUDIO_GREATER_EQUAL_0_10, reason="torchaudio>=0.10.0 is required") @pytest.mark.parametrize( "preds, fs, fast, norm", [ diff --git a/tests/unittests/audio/test_stoi.py b/tests/unittests/audio/test_stoi.py index 2d872507401..d7998aaf8b2 100644 --- a/tests/unittests/audio/test_stoi.py +++ b/tests/unittests/audio/test_stoi.py @@ -20,7 +20,6 @@ from torch import Tensor from torchmetrics.audio import ShortTimeObjectiveIntelligibility from torchmetrics.functional.audio import short_time_objective_intelligibility -from torchmetrics.utilities.imports import _TORCH_GREATER_EQUAL_2_0 from unittests import _Input from unittests._helpers import seed_all @@ -121,14 +120,9 @@ def test_error_on_different_shape(metric_class=ShortTimeObjectiveIntelligibility metric(torch.randn(100), torch.randn(50)) -@pytest.mark.skipif(not _TORCH_GREATER_EQUAL_2_0, reason="precision issue with older torch") def test_on_real_audio(): """Test that metric works on real audio signal.""" rate, ref = wavfile.read(_SAMPLE_AUDIO_SPEECH) rate, deg = wavfile.read(_SAMPLE_AUDIO_SPEECH_BAB_DB) - assert torch.allclose( - short_time_objective_intelligibility(torch.from_numpy(deg), torch.from_numpy(ref), rate).float(), - torch.tensor(0.6739177), - rtol=0.0001, - atol=1e-4, - ) + stoi = short_time_objective_intelligibility(torch.from_numpy(deg), torch.from_numpy(ref), rate) + assert torch.allclose(stoi.float(), torch.tensor(0.6739177), rtol=1e-2, atol=5e-3) diff --git a/tests/unittests/bases/test_collections.py b/tests/unittests/bases/test_collections.py index 55062ccbe29..77b333ce66a 100644 --- a/tests/unittests/bases/test_collections.py +++ b/tests/unittests/bases/test_collections.py @@ -33,7 +33,6 @@ MultilabelAveragePrecision, ) from torchmetrics.utilities.checks import _allclose_recursive -from torchmetrics.utilities.imports import _TORCH_GREATER_EQUAL_2_0 from unittests._helpers import seed_all from unittests._helpers.testers import DummyMetricDiff, DummyMetricMultiOutputDict, DummyMetricSum @@ -151,7 +150,6 @@ def test_metric_collection_args_kwargs(tmpdir): assert metric_collection["DummyMetricDiff"].x == -20 -@pytest.mark.skipif(not _TORCH_GREATER_EQUAL_2_0, reason="Test requires torch 2.0 or higher") @pytest.mark.parametrize( ("prefix", "postfix"), [ diff --git a/tests/unittests/classification/test_calibration_error.py b/tests/unittests/classification/test_calibration_error.py index a2000cc984e..86cfded8246 100644 --- a/tests/unittests/classification/test_calibration_error.py +++ b/tests/unittests/classification/test_calibration_error.py @@ -29,7 +29,6 @@ multiclass_calibration_error, ) from torchmetrics.metric import Metric -from torchmetrics.utilities.imports import _TORCH_GREATER_EQUAL_1_13 from unittests import NUM_CLASSES from unittests._helpers import seed_all @@ -113,8 +112,6 @@ def test_binary_calibration_error_differentiability(self, inputs): def test_binary_calibration_error_dtype_cpu(self, inputs, dtype): """Test dtype support of the metric on CPU.""" preds, target = inputs - if dtype == torch.half and not _TORCH_GREATER_EQUAL_1_13: - pytest.xfail(reason="torch.linspace in metric not supported before pytorch v1.13 for cpu + half") if (preds < 0).any() and dtype == torch.half: pytest.xfail(reason="torch.sigmoid in metric does not support cpu + half precision") self.run_precision_test_cpu( @@ -129,8 +126,6 @@ def test_binary_calibration_error_dtype_cpu(self, inputs, dtype): @pytest.mark.parametrize("dtype", [torch.half, torch.double]) def test_binary_calibration_error_dtype_gpu(self, inputs, dtype): """Test dtype support of the metric on GPU.""" - if dtype == torch.half and not _TORCH_GREATER_EQUAL_1_13: - pytest.xfail(reason="torch.searchsorted in metric not supported before pytorch v1.13 for gpu + half") preds, target = inputs self.run_precision_test_gpu( preds=preds, diff --git a/tests/unittests/classification/test_sensitivity_specificity.py b/tests/unittests/classification/test_sensitivity_specificity.py index df01b67e4ab..e0689859dd4 100644 --- a/tests/unittests/classification/test_sensitivity_specificity.py +++ b/tests/unittests/classification/test_sensitivity_specificity.py @@ -33,7 +33,7 @@ multilabel_sensitivity_at_specificity, ) from torchmetrics.metric import Metric -from torchmetrics.utilities.imports import _SKLEARN_GREATER_EQUAL_1_3, _TORCH_GREATER_EQUAL_1_11 +from torchmetrics.utilities.imports import _SKLEARN_GREATER_EQUAL_1_3 from unittests import NUM_CLASSES from unittests._helpers import seed_all @@ -84,7 +84,6 @@ def _reference_sklearn_sensitivity_at_specificity_binary(preds, target, min_spec @pytest.mark.skipif(not _SKLEARN_GREATER_EQUAL_1_3, reason="metric does not support scikit-learn versions below 1.3") -@pytest.mark.skipif(not _TORCH_GREATER_EQUAL_1_11, reason="metric does not support torch versions below 1.11") @pytest.mark.parametrize("inputs", (_binary_cases[1], _binary_cases[2], _binary_cases[4], _binary_cases[5])) class TestBinarySensitivityAtSpecificity(MetricTester): """Test class for `BinarySensitivityAtSpecificity` metric.""" @@ -211,7 +210,6 @@ def _reference_sklearn_sensitivity_at_specificity_multiclass(preds, target, min_ @pytest.mark.skipif(not _SKLEARN_GREATER_EQUAL_1_3, reason="metric does not support scikit-learn versions below 1.3") -@pytest.mark.skipif(not _TORCH_GREATER_EQUAL_1_11, reason="metric does not support torch versions below 1.11") @pytest.mark.parametrize( "inputs", (_multiclass_cases[1], _multiclass_cases[2], _multiclass_cases[4], _multiclass_cases[5]) ) @@ -343,7 +341,6 @@ def _reference_sklearn_sensitivity_at_specificity_multilabel(preds, target, min_ @pytest.mark.skipif(not _SKLEARN_GREATER_EQUAL_1_3, reason="metric does not support scikit-learn versions below 1.3") -@pytest.mark.skipif(not _TORCH_GREATER_EQUAL_1_11, reason="metric does not support torch versions below 1.11") @pytest.mark.parametrize( "inputs", (_multilabel_cases[1], _multilabel_cases[2], _multilabel_cases[4], _multilabel_cases[5]) ) @@ -463,7 +460,6 @@ def test_multilabel_sensitivity_at_specificity_threshold_arg(self, inputs, min_s assert all(torch.allclose(r1[i], r2[i]) for i in range(len(r1))) -@pytest.mark.skipif(not _TORCH_GREATER_EQUAL_1_11, reason="metric does not support torch versions below 1.11") @pytest.mark.parametrize( "metric", [ @@ -479,7 +475,6 @@ def test_valid_input_thresholds(recwarn, metric, thresholds): assert len(recwarn) == 0, "Warning was raised when it should not have been." -@pytest.mark.skipif(not _TORCH_GREATER_EQUAL_1_11, reason="metric does not support torch versions below 1.11") @pytest.mark.parametrize( ("metric", "kwargs"), [ diff --git a/tests/unittests/detection/test_intersection.py b/tests/unittests/detection/test_intersection.py index a028a014ea1..e76ce966474 100644 --- a/tests/unittests/detection/test_intersection.py +++ b/tests/unittests/detection/test_intersection.py @@ -24,10 +24,9 @@ from torchmetrics.functional.detection.diou import distance_intersection_over_union from torchmetrics.functional.detection.giou import generalized_intersection_over_union from torchmetrics.functional.detection.iou import intersection_over_union -from torchmetrics.utilities.imports import _TORCHVISION_GREATER_EQUAL_0_13 +from torchmetrics.utilities.imports import _TORCHVISION_AVAILABLE -# todo: check if some older versions have these functions too? -if _TORCHVISION_GREATER_EQUAL_0_13: +if _TORCHVISION_AVAILABLE: from torchvision.ops import box_iou as tv_iou from torchvision.ops import complete_box_iou as tv_ciou from torchvision.ops import distance_box_iou as tv_diou @@ -185,7 +184,6 @@ def _add_noise(x, scale=10): (GeneralizedIntersectionOverUnion, generalized_intersection_over_union, tv_giou), ], ) -@pytest.mark.skipif(not _TORCHVISION_GREATER_EQUAL_0_13, reason="test requires torchvision >= 0.13") class TestIntersectionMetrics(MetricTester): """Tester class for the different intersection metrics.""" diff --git a/tests/unittests/detection/test_map.py b/tests/unittests/detection/test_map.py index 5b869488131..221f1f87aef 100644 --- a/tests/unittests/detection/test_map.py +++ b/tests/unittests/detection/test_map.py @@ -29,14 +29,11 @@ from torchmetrics.utilities.imports import ( _FASTER_COCO_EVAL_AVAILABLE, _PYCOCOTOOLS_AVAILABLE, - _TORCHVISION_GREATER_EQUAL_0_8, ) from unittests._helpers.testers import MetricTester from unittests.detection import _DETECTION_BBOX, _DETECTION_SEGM, _DETECTION_VAL -_pytest_condition = not (_PYCOCOTOOLS_AVAILABLE and _TORCHVISION_GREATER_EQUAL_0_8) - def _skip_if_faster_coco_eval_missing(backend): if backend == "faster_coco_eval" and not _FASTER_COCO_EVAL_AVAILABLE: @@ -65,7 +62,7 @@ def _generate_coco_inputs(iou_type): _coco_segm_input = _generate_coco_inputs("segm") -@pytest.mark.skipif(_pytest_condition, reason="test requires that torchvision=>0.8.0 and pycocotools is installed") +@pytest.mark.skipif(_PYCOCOTOOLS_AVAILABLE, reason="test requires that torchvision=>0.8.0 and pycocotools is installed") @pytest.mark.parametrize("iou_type", ["bbox", "segm"]) @pytest.mark.parametrize("backend", ["pycocotools", "faster_coco_eval"]) def test_tm_to_coco(tmpdir, iou_type, backend): @@ -175,7 +172,7 @@ def _compare_against_coco_fn(preds, target, iou_type, iou_thresholds=None, rec_t } -@pytest.mark.skipif(_pytest_condition, reason="test requires that torchvision=>0.8.0 and pycocotools is installed") +@pytest.mark.skipif(_PYCOCOTOOLS_AVAILABLE, reason="test requires that torchvision=>0.8.0 and pycocotools is installed") @pytest.mark.parametrize("iou_type", ["bbox", "segm"]) @pytest.mark.parametrize("ddp", [pytest.param(True, marks=pytest.mark.DDP), False]) @pytest.mark.parametrize("backend", ["pycocotools", "faster_coco_eval"]) @@ -450,7 +447,7 @@ def _generate_random_segm_input(device, batch_size=2, num_preds_size=10, num_gt_ return preds, targets -@pytest.mark.skipif(_pytest_condition, reason="test requires that torchvision=>0.8.0 is installed") +@pytest.mark.skipif(_PYCOCOTOOLS_AVAILABLE, reason="test requires that torchvision=>0.8.0 is installed") @pytest.mark.parametrize( "backend", [ diff --git a/tests/unittests/detection/test_modified_panoptic_quality.py b/tests/unittests/detection/test_modified_panoptic_quality.py index 1d5a067a609..4c864d0e9af 100644 --- a/tests/unittests/detection/test_modified_panoptic_quality.py +++ b/tests/unittests/detection/test_modified_panoptic_quality.py @@ -18,7 +18,6 @@ import torch from torchmetrics.detection import ModifiedPanopticQuality from torchmetrics.functional.detection import modified_panoptic_quality -from torchmetrics.utilities.imports import _TORCH_GREATER_EQUAL_1_12 from unittests import _Input from unittests._helpers import seed_all @@ -77,7 +76,6 @@ def _reference_fn_1_2(preds, target) -> np.ndarray: return np.array([23 / 30]) -@pytest.mark.skipif(not _TORCH_GREATER_EQUAL_1_12, reason="PanopticQuality metric only supports PyTorch >= 1.12") class TestModifiedPanopticQuality(MetricTester): """Test class for `ModifiedPanopticQuality` metric.""" @@ -113,7 +111,6 @@ def test_panoptic_quality_functional(self): ) -@pytest.mark.skipif(not _TORCH_GREATER_EQUAL_1_12, reason="PanopticQuality metric only supports PyTorch >= 1.12") def test_empty_metric(): """Test empty metric.""" with pytest.raises(ValueError, match="At least one of `things` and `stuffs` must be non-empty"): @@ -123,7 +120,6 @@ def test_empty_metric(): assert torch.isnan(metric.compute()) -@pytest.mark.skipif(not _TORCH_GREATER_EQUAL_1_12, reason="PanopticQuality metric only supports PyTorch >= 1.12") def test_error_on_wrong_input(): """Test class input validation.""" with pytest.raises(TypeError, match="Expected argument `stuffs` to contain `int` categories.*"): @@ -166,7 +162,6 @@ def test_error_on_wrong_input(): metric.update(preds, preds) -@pytest.mark.skipif(not _TORCH_GREATER_EQUAL_1_12, reason="PanopticQuality metric only supports PyTorch >= 1.12") def test_extreme_values(): """Test that the metric returns expected values in trivial cases.""" # Exact match between preds and target => metric is 1 @@ -175,7 +170,6 @@ def test_extreme_values(): assert modified_panoptic_quality(_INPUTS_0.target[0], _INPUTS_0.target[0] + 1, **_ARGS_0) == 0.0 -@pytest.mark.skipif(not _TORCH_GREATER_EQUAL_1_12, reason="PanopticQuality metric only supports PyTorch >= 1.12") @pytest.mark.parametrize( ("inputs", "args", "cat_dim"), [ diff --git a/tests/unittests/detection/test_panoptic_quality.py b/tests/unittests/detection/test_panoptic_quality.py index c7333ccac06..245fb4097fc 100644 --- a/tests/unittests/detection/test_panoptic_quality.py +++ b/tests/unittests/detection/test_panoptic_quality.py @@ -18,7 +18,6 @@ import torch from torchmetrics.detection.panoptic_qualities import PanopticQuality from torchmetrics.functional.detection.panoptic_qualities import panoptic_quality -from torchmetrics.utilities.imports import _TORCH_GREATER_EQUAL_1_12 from unittests import _Input from unittests._helpers import seed_all @@ -105,7 +104,6 @@ def _reference_fn_class_order(preds, target) -> np.ndarray: return np.array([1, 0, 2 / 3]) -@pytest.mark.skipif(not _TORCH_GREATER_EQUAL_1_12, reason="PanopticQuality metric only supports PyTorch >= 1.12") class TestPanopticQuality(MetricTester): """Test class for `PanopticQuality` metric.""" @@ -147,7 +145,6 @@ def test_panoptic_quality_functional(self): ) -@pytest.mark.skipif(not _TORCH_GREATER_EQUAL_1_12, reason="PanopticQuality metric only supports PyTorch >= 1.12") def test_empty_metric(): """Test empty metric.""" with pytest.raises(ValueError, match="At least one of `things` and `stuffs` must be non-empty"): @@ -157,7 +154,6 @@ def test_empty_metric(): assert torch.isnan(metric.compute()) -@pytest.mark.skipif(not _TORCH_GREATER_EQUAL_1_12, reason="PanopticQuality metric only supports PyTorch >= 1.12") def test_error_on_wrong_input(): """Test class input validation.""" with pytest.raises(TypeError, match="Expected argument `stuffs` to contain `int` categories.*"): @@ -200,7 +196,6 @@ def test_error_on_wrong_input(): metric.update(preds, preds) -@pytest.mark.skipif(not _TORCH_GREATER_EQUAL_1_12, reason="PanopticQuality metric only supports PyTorch >= 1.12") def test_extreme_values(): """Test that the metric returns expected values in trivial cases.""" # Exact match between preds and target => metric is 1 @@ -209,7 +204,6 @@ def test_extreme_values(): assert panoptic_quality(_INPUTS_0.target[0], _INPUTS_0.target[0] + 1, **_ARGS_0) == 0.0 -@pytest.mark.skipif(not _TORCH_GREATER_EQUAL_1_12, reason="PanopticQuality metric only supports PyTorch >= 1.12") @pytest.mark.parametrize( ("inputs", "args", "cat_dim"), [ diff --git a/tests/unittests/regression/test_kendall.py b/tests/unittests/regression/test_kendall.py index 017179069e0..69c32106aba 100644 --- a/tests/unittests/regression/test_kendall.py +++ b/tests/unittests/regression/test_kendall.py @@ -21,7 +21,7 @@ from scipy.stats import kendalltau from torchmetrics.functional.regression.kendall import kendall_rank_corrcoef from torchmetrics.regression.kendall import KendallRankCorrCoef -from torchmetrics.utilities.imports import _SCIPY_GREATER_EQUAL_1_8, _TORCH_LOWER_2_0 +from torchmetrics.utilities.imports import _SCIPY_GREATER_EQUAL_1_8 from unittests import BATCH_SIZE, EXTRA_DIM, NUM_BATCHES, _Input from unittests._helpers import seed_all @@ -84,11 +84,7 @@ def _reference_scipy_kendall(preds, target, alternative, variant): class TestKendallRankCorrCoef(MetricTester): """Test class for `KendallRankCorrCoef` metric.""" - # TODO - @pytest.mark.skipif( - sys.platform == "darwin" and not _TORCH_LOWER_2_0, - reason="Tests are not working on mac for newer version of PyTorch.", - ) + @pytest.mark.skipif(sys.platform == "darwin", reason="Fails on MacOS") # TODO: investigate @pytest.mark.parametrize("ddp", [pytest.param(True, marks=pytest.mark.DDP), False]) def test_kendall_rank_corrcoef(self, preds, target, alternative, variant, ddp): """Test class implementation of metric.""" diff --git a/tests/unittests/utilities/test_plot.py b/tests/unittests/utilities/test_plot.py index aacbf050dac..5b85a01af5a 100644 --- a/tests/unittests/utilities/test_plot.py +++ b/tests/unittests/utilities/test_plot.py @@ -168,10 +168,6 @@ WordInfoLost, WordInfoPreserved, ) -from torchmetrics.utilities.imports import ( - _TORCH_GREATER_EQUAL_1_12, - _TORCHAUDIO_GREATER_EQUAL_0_10, -) from torchmetrics.utilities.plot import _get_col_row_split from torchmetrics.wrappers import ( BootStrapper, @@ -316,7 +312,6 @@ _audio_input, None, id="speech_reverberation_modulation_energy_ratio", - marks=pytest.mark.skipif(not _TORCHAUDIO_GREATER_EQUAL_0_10, reason="test requires torchaudio>=0.10"), ), pytest.param( partial(PermutationInvariantTraining, metric_func=scale_invariant_signal_noise_ratio, eval_func="max"), @@ -342,9 +337,6 @@ _panoptic_input, _panoptic_input, id="panoptic quality", - marks=pytest.mark.skipif( - not _TORCH_GREATER_EQUAL_1_12, reason="Panoptic Quality metric requires PyTorch 1.12 or later" - ), ), pytest.param(BinaryAveragePrecision, _rand_input, _binary_randint_input, id="binary average precision"), pytest.param( diff --git a/tests/unittests/utilities/test_utilities.py b/tests/unittests/utilities/test_utilities.py index ee46adc349d..ca082dec969 100644 --- a/tests/unittests/utilities/test_utilities.py +++ b/tests/unittests/utilities/test_utilities.py @@ -31,7 +31,7 @@ ) from torchmetrics.utilities.distributed import class_reduce, reduce from torchmetrics.utilities.exceptions import TorchMetricsUserWarning -from torchmetrics.utilities.imports import _TORCH_GREATER_EQUAL_1_13, _TORCH_GREATER_EQUAL_2_2 +from torchmetrics.utilities.imports import _TORCH_GREATER_EQUAL_2_2 def test_prints(): @@ -172,9 +172,6 @@ def test_recursive_allclose(inputs, expected): @pytest.mark.skipif(not torch.cuda.is_available(), reason="test requires GPU") @pytest.mark.xfail(sys.platform == "win32", reason="test will only fail on non-windows systems") -@pytest.mark.skipif( - not _TORCH_GREATER_EQUAL_1_13, reason="earlier versions was silently non-deterministic, even in deterministic mode" -) def test_cumsum_still_not_supported(use_deterministic_algorithms): """Make sure that cumsum on gpu and deterministic mode still fails. @@ -219,8 +216,6 @@ def _reference_topk(x, dim, k): @pytest.mark.parametrize("dim", [0, 1]) def test_custom_topk(dtype, k, dim): """Test custom topk implementation.""" - if dtype == torch.half and not _TORCH_GREATER_EQUAL_1_13: - pytest.skip("half precision topk not supported in Pytorch < 1.13") x = torch.randn(100, 10, dtype=dtype) top_k = select_topk(x, dim=dim, topk=k) assert top_k.shape == (100, 10)