diff --git a/monai/transforms/lazy/utils.py b/monai/transforms/lazy/utils.py index 75f1e3529d0..0e9ff6f9716 100644 --- a/monai/transforms/lazy/utils.py +++ b/monai/transforms/lazy/utils.py @@ -192,6 +192,13 @@ def resample(data: torch.Tensor, matrix: NdarrayOrTensor, kwargs: dict | None = } ndim = len(matrix) - 1 img = convert_to_tensor(data=data, track_meta=monai.data.get_track_meta()) + if not (torch.is_floating_point(img) or torch.is_complex(img)): + warnings.warn( + f"Lazy resampling computes in floating point and converts the input of dtype {img.dtype} to " + "float32; the original data type is not preserved. For integer data such as label maps, set " + "`lazy=False` for the affected transforms (or cast back afterwards) if the data type must be preserved.", + stacklevel=2, + ) init_affine = monai.data.to_affine_nd(ndim, img.affine) spatial_size = kwargs.get(LazyAttr.SHAPE, None) out_spatial_size = img.peek_pending_shape() if spatial_size is None else spatial_size diff --git a/tests/transforms/functional/test_resample.py b/tests/transforms/functional/test_resample.py index 40d264598d3..062a1b0b4de 100644 --- a/tests/transforms/functional/test_resample.py +++ b/tests/transforms/functional/test_resample.py @@ -12,6 +12,7 @@ from __future__ import annotations import unittest +import warnings import torch from parameterized import parameterized @@ -45,6 +46,21 @@ def test_resample_function_impl(self, img, matrix, expected): out_1 = resample(img, matrix, {"lazy_resample_mode": "other value", "lazy_dtype": torch.float}) self.assertIs(out.dtype, out_1.dtype) # testing dtype in different lazy_resample_mode + def test_resample_warns_on_non_float_dtype(self): + """Lazy resampling upcasts non-floating-point inputs to float32; the user should be warned (see issue #6713).""" + img = convert_to_tensor(get_arange_img((3, 3)), dtype=torch.uint8) + with self.assertWarns(Warning): + out = resample(img, torch.eye(3), {"lazy_resample_mode": "auto"}) + self.assertIs(out.dtype, torch.float32) + self.assertIs(img.dtype, torch.uint8) # the input tensor itself is not mutated + + def test_resample_no_warning_for_float_dtype(self): + """Float32 inputs do not trigger the lazy resampling dtype warning.""" + img = convert_to_tensor(get_arange_img((3, 3)), dtype=torch.float32) + with warnings.catch_warnings(): + warnings.simplefilter("error") # turn any warning into an error + resample(img, torch.eye(3), {"lazy_resample_mode": "auto"}) + if __name__ == "__main__": unittest.main()