From e3082b785b31bed23cc3582d906d5f12910997f4 Mon Sep 17 00:00:00 2001 From: Wenqi Li Date: Tue, 14 Mar 2023 23:38:17 +0000 Subject: [PATCH 01/10] update the default flag Signed-off-by: Wenqi Li --- monai/data/image_writer.py | 15 ++++++++++----- monai/transforms/io/array.py | 1 + monai/transforms/io/dictionary.py | 1 + tests/test_image_rw.py | 2 +- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/monai/data/image_writer.py b/monai/data/image_writer.py index 0274c44900..7a9cdcb6b4 100644 --- a/monai/data/image_writer.py +++ b/monai/data/image_writer.py @@ -373,11 +373,11 @@ class ITKWriter(ImageWriter): output_dtype: DtypeLike = None channel_dim: int | None - def __init__(self, output_dtype: DtypeLike = np.float32, affine_lps_to_ras: bool = True, **kwargs): + def __init__(self, output_dtype: DtypeLike = np.float32, affine_lps_to_ras: bool | None = None, **kwargs): """ Args: output_dtype: output data type. - affine_lps_to_ras: whether to convert the affine matrix from "LPS" to "RAS". Defaults to ``True``. + affine_lps_to_ras: whether to convert the affine matrix from "LPS" to "RAS". Defaults to ``None``. Set to ``True`` to be consistent with ``NibabelWriter``, otherwise the affine matrix is assumed already in the ITK convention. kwargs: keyword arguments passed to ``ImageWriter``. @@ -478,7 +478,7 @@ def create_backend_obj( channel_dim: int | None = 0, affine: NdarrayOrTensor | None = None, dtype: DtypeLike = np.float32, - affine_lps_to_ras: bool = True, + affine_lps_to_ras: bool | None = None, **kwargs, ): """ @@ -489,7 +489,7 @@ def create_backend_obj( channel_dim: channel dimension of the data array. This is used to create a Vector Image if it is not ``None``. affine: affine matrix of the data array. This is used to compute `spacing`, `direction` and `origin`. dtype: output data type. - affine_lps_to_ras: whether to convert the affine matrix from "LPS" to "RAS". Defaults to ``True``. + affine_lps_to_ras: whether to convert the affine matrix from "LPS" to "RAS". Defaults to ``None``. Set to ``True`` to be consistent with ``NibabelWriter``, otherwise the affine matrix is assumed already in the ITK convention. kwargs: keyword arguments. Current `itk.GetImageFromArray` will read ``ttype`` from this dictionary. @@ -497,8 +497,13 @@ def create_backend_obj( see also: - https://github.com/InsightSoftwareConsortium/ITK/blob/v5.2.1/Wrapping/Generators/Python/itk/support/extras.py#L389 + """ - if isinstance(data_array, MetaTensor) and data_array.meta.get(MetaKeys.SPACE, SpaceKeys.LPS) != SpaceKeys.LPS: + if ( + isinstance(data_array, MetaTensor) + and affine_lps_to_ras is None + and data_array.meta.get(MetaKeys.SPACE, SpaceKeys.LPS) != SpaceKeys.LPS + ): affine_lps_to_ras = False # do the converting from LPS to RAS only if the space type is currently LPS. data_array = super().create_backend_obj(data_array) _is_vec = channel_dim is not None diff --git a/monai/transforms/io/array.py b/monai/transforms/io/array.py index 56d284d46f..92abafcec4 100644 --- a/monai/transforms/io/array.py +++ b/monai/transforms/io/array.py @@ -440,6 +440,7 @@ def set_options(self, init_kwargs=None, data_kwargs=None, meta_kwargs=None, writ self.meta_kwargs.update(meta_kwargs) if write_kwargs is not None: self.write_kwargs.update(write_kwargs) + return self def __call__(self, img: torch.Tensor | np.ndarray, meta_data: dict | None = None): """ diff --git a/monai/transforms/io/dictionary.py b/monai/transforms/io/dictionary.py index ec2e5e403d..47dfbf7e28 100644 --- a/monai/transforms/io/dictionary.py +++ b/monai/transforms/io/dictionary.py @@ -296,6 +296,7 @@ def __init__( def set_options(self, init_kwargs=None, data_kwargs=None, meta_kwargs=None, write_kwargs=None): self.saver.set_options(init_kwargs, data_kwargs, meta_kwargs, write_kwargs) + return self def __call__(self, data): d = dict(data) diff --git a/tests/test_image_rw.py b/tests/test_image_rw.py index 42f9b0c4e7..79e51c53eb 100644 --- a/tests/test_image_rw.py +++ b/tests/test_image_rw.py @@ -167,7 +167,7 @@ def nrrd_rw(self, test_data, reader, writer, dtype, resample=True): filepath = f"testfile_{ndim}d" saver = SaveImage( output_dir=self.test_dir, output_ext=output_ext, resample=resample, separate_folder=False, writer=writer - ) + ).set_options(init_kwargs={"affine_lps_to_ras": True}) test_data = MetaTensor( p(test_data), meta={"filename_or_obj": f"{filepath}{output_ext}", "spatial_shape": test_data.shape} ) From 2a4cb8d5cda334aa5cbf6c54d32adecb108037c2 Mon Sep 17 00:00:00 2001 From: Wenqi Li Date: Wed, 15 Mar 2023 15:42:16 +0000 Subject: [PATCH 02/10] update based on comments Signed-off-by: Wenqi Li --- monai/data/image_writer.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/monai/data/image_writer.py b/monai/data/image_writer.py index 7a9cdcb6b4..b467a5ae99 100644 --- a/monai/data/image_writer.py +++ b/monai/data/image_writer.py @@ -373,11 +373,11 @@ class ITKWriter(ImageWriter): output_dtype: DtypeLike = None channel_dim: int | None - def __init__(self, output_dtype: DtypeLike = np.float32, affine_lps_to_ras: bool | None = None, **kwargs): + def __init__(self, output_dtype: DtypeLike = np.float32, affine_lps_to_ras: bool | None = True, **kwargs): """ Args: output_dtype: output data type. - affine_lps_to_ras: whether to convert the affine matrix from "LPS" to "RAS". Defaults to ``None``. + affine_lps_to_ras: whether to convert the affine matrix from "LPS" to "RAS". Defaults to ``True``. Set to ``True`` to be consistent with ``NibabelWriter``, otherwise the affine matrix is assumed already in the ITK convention. kwargs: keyword arguments passed to ``ImageWriter``. @@ -478,7 +478,7 @@ def create_backend_obj( channel_dim: int | None = 0, affine: NdarrayOrTensor | None = None, dtype: DtypeLike = np.float32, - affine_lps_to_ras: bool | None = None, + affine_lps_to_ras: bool | None = True, **kwargs, ): """ @@ -489,7 +489,7 @@ def create_backend_obj( channel_dim: channel dimension of the data array. This is used to create a Vector Image if it is not ``None``. affine: affine matrix of the data array. This is used to compute `spacing`, `direction` and `origin`. dtype: output data type. - affine_lps_to_ras: whether to convert the affine matrix from "LPS" to "RAS". Defaults to ``None``. + affine_lps_to_ras: whether to convert the affine matrix from "LPS" to "RAS". Defaults to ``True``. Set to ``True`` to be consistent with ``NibabelWriter``, otherwise the affine matrix is assumed already in the ITK convention. kwargs: keyword arguments. Current `itk.GetImageFromArray` will read ``ttype`` from this dictionary. From b0ca3921de98612b30c1d5c1e883637a7b072b1b Mon Sep 17 00:00:00 2001 From: Wenqi Li Date: Wed, 15 Mar 2023 16:20:18 +0000 Subject: [PATCH 03/10] update channel_dim None case Signed-off-by: Wenqi Li --- monai/data/image_writer.py | 9 ++++++--- tests/test_itk_writer.py | 11 +++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/monai/data/image_writer.py b/monai/data/image_writer.py index b467a5ae99..94b31c164c 100644 --- a/monai/data/image_writer.py +++ b/monai/data/image_writer.py @@ -414,9 +414,12 @@ def set_data_array( spatial_ndim=kwargs.pop("spatial_ndim", 3), contiguous=kwargs.pop("contiguous", True), ) - self.channel_dim = ( - channel_dim if self.data_obj is not None and len(self.data_obj.shape) >= _r else None - ) # channel dim is at the end + if channel_dim is None: + self.channel_dim = -1 # after convert_to_channel_last the last dim is the channel + else: + self.channel_dim = ( + channel_dim if self.data_obj is not None and len(self.data_obj.shape) >= _r else None + ) # channel dim is at the end def set_metadata(self, meta_dict: Mapping | None = None, resample: bool = True, **options): """ diff --git a/tests/test_itk_writer.py b/tests/test_itk_writer.py index 869ec7b947..75f848ec01 100644 --- a/tests/test_itk_writer.py +++ b/tests/test_itk_writer.py @@ -52,6 +52,17 @@ def test_rgb(self): np.testing.assert_allclose(output.shape, (5, 5, 3)) np.testing.assert_allclose(output[1, 1], (5, 5, 4)) + def test_no_channel(self): + with tempfile.TemporaryDirectory() as tempdir: + fname = os.path.join(tempdir, "testing.nii.gz") + writer = ITKWriter(output_dtype=np.uint8) + writer.set_data_array(np.arange(48).reshape(3, 4, 4), channel_dim=None) + writer.write(fname) + + output = np.asarray(itk.imread(fname)) + np.testing.assert_allclose(output.shape, (4, 3, 4)) + np.testing.assert_allclose(output[1, 1], (20, 21, 22, 23)) + if __name__ == "__main__": unittest.main() From ff22420f4876b01eeb6232b72143b28e1837ff1b Mon Sep 17 00:00:00 2001 From: Wenqi Li Date: Wed, 15 Mar 2023 16:33:14 +0000 Subject: [PATCH 04/10] update docstring Signed-off-by: Wenqi Li --- monai/data/image_writer.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/monai/data/image_writer.py b/monai/data/image_writer.py index 94b31c164c..25b5d83226 100644 --- a/monai/data/image_writer.py +++ b/monai/data/image_writer.py @@ -380,6 +380,7 @@ def __init__(self, output_dtype: DtypeLike = np.float32, affine_lps_to_ras: bool affine_lps_to_ras: whether to convert the affine matrix from "LPS" to "RAS". Defaults to ``True``. Set to ``True`` to be consistent with ``NibabelWriter``, otherwise the affine matrix is assumed already in the ITK convention. + Set to ``None`` to use ``data_array.meta[MetaKeys.SPACE]`` to determine the flag. kwargs: keyword arguments passed to ``ImageWriter``. The constructor will create ``self.output_dtype`` internally. @@ -495,6 +496,7 @@ def create_backend_obj( affine_lps_to_ras: whether to convert the affine matrix from "LPS" to "RAS". Defaults to ``True``. Set to ``True`` to be consistent with ``NibabelWriter``, otherwise the affine matrix is assumed already in the ITK convention. + Set to ``None`` to use ``data_array.meta[MetaKeys.SPACE]`` to determine the flag. kwargs: keyword arguments. Current `itk.GetImageFromArray` will read ``ttype`` from this dictionary. see also: @@ -502,12 +504,10 @@ def create_backend_obj( - https://github.com/InsightSoftwareConsortium/ITK/blob/v5.2.1/Wrapping/Generators/Python/itk/support/extras.py#L389 """ - if ( - isinstance(data_array, MetaTensor) - and affine_lps_to_ras is None - and data_array.meta.get(MetaKeys.SPACE, SpaceKeys.LPS) != SpaceKeys.LPS - ): - affine_lps_to_ras = False # do the converting from LPS to RAS only if the space type is currently LPS. + if isinstance(data_array, MetaTensor) and affine_lps_to_ras is None: + affine_lps_to_ras = ( + data_array.meta.get(MetaKeys.SPACE, SpaceKeys.LPS) != SpaceKeys.LPS + ) # do the converting from LPS to RAS only if the space type is currently LPS. data_array = super().create_backend_obj(data_array) _is_vec = channel_dim is not None if _is_vec: From a7888cdcac0b336ebeda93e8de4d982652d3e7cc Mon Sep 17 00:00:00 2001 From: Wenqi Li Date: Wed, 15 Mar 2023 16:52:49 +0000 Subject: [PATCH 05/10] update docstrings Signed-off-by: Wenqi Li --- monai/networks/layers/filtering.py | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/monai/networks/layers/filtering.py b/monai/networks/layers/filtering.py index b8bfe9a3bc..0ff1187dcc 100644 --- a/monai/networks/layers/filtering.py +++ b/monai/networks/layers/filtering.py @@ -32,13 +32,10 @@ class BilateralFilter(torch.autograd.Function): Args: input: input tensor. - spatial_sigma: the standard deviation of the spatial blur. Higher values can hurt performance when not using the approximate method (see fast approx). - color_sigma: the standard deviation of the color blur. Lower values preserve edges better whilst higher values tend to a simple gaussian spatial blur. - fast approx: This flag chooses between two implementations. The approximate method may produce artifacts in some scenarios whereas the exact solution may be intolerably slow for high spatial standard deviations. @@ -49,6 +46,7 @@ class BilateralFilter(torch.autograd.Function): @staticmethod def forward(ctx, input, spatial_sigma=5, color_sigma=0.5, fast_approx=True): + """autograd forward""" ctx.ss = spatial_sigma ctx.cs = color_sigma ctx.fa = fast_approx @@ -57,6 +55,7 @@ def forward(ctx, input, spatial_sigma=5, color_sigma=0.5, fast_approx=True): @staticmethod def backward(ctx, grad_output): + """autograd backward""" spatial_sigma, color_sigma, fast_approx = ctx.ss, ctx.cs, ctx.fa grad_input = _C.bilateral_filter(grad_output, spatial_sigma, color_sigma, fast_approx) return grad_input, None, None, None @@ -74,9 +73,7 @@ class PHLFilter(torch.autograd.Function): Args: input: input tensor to be filtered. - features: feature tensor used to filter the input. - sigmas: the standard deviations of each feature in the filter. Returns: @@ -112,13 +109,9 @@ class TrainableBilateralFilterFunction(torch.autograd.Function): Args: input: input tensor to be filtered. - sigma x: trainable standard deviation of the spatial filter kernel in x direction. - sigma y: trainable standard deviation of the spatial filter kernel in y direction. - sigma z: trainable standard deviation of the spatial filter kernel in z direction. - color sigma: trainable standard deviation of the intensity range kernel. This filter parameter determines the degree of edge preservation. @@ -198,11 +191,9 @@ class TrainableBilateralFilter(torch.nn.Module): Args: input: input tensor to be filtered. - spatial_sigma: tuple (sigma_x, sigma_y, sigma_z) initializing the trainable standard deviations of the spatial filter kernels. Tuple length must equal the number of spatial input dimensions. - color_sigma: trainable standard deviation of the intensity range kernel. This filter parameter determines the degree of edge preservation. @@ -278,15 +269,10 @@ class TrainableJointBilateralFilterFunction(torch.autograd.Function): Args: input: input tensor to be filtered. - guide: guidance image tensor to be used during filtering. - sigma x: trainable standard deviation of the spatial filter kernel in x direction. - sigma y: trainable standard deviation of the spatial filter kernel in y direction. - sigma z: trainable standard deviation of the spatial filter kernel in z direction. - color sigma: trainable standard deviation of the intensity range kernel. This filter parameter determines the degree of edge preservation. @@ -371,13 +357,10 @@ class TrainableJointBilateralFilter(torch.nn.Module): Args: input: input tensor to be filtered. - guide: guidance image tensor to be used during filtering. - spatial_sigma: tuple (sigma_x, sigma_y, sigma_z) initializing the trainable standard deviations of the spatial filter kernels. Tuple length must equal the number of spatial input dimensions. - color_sigma: trainable standard deviation of the intensity range kernel. This filter parameter determines the degree of edge preservation. From 8676c55dfe23e02a8ce5e18a54742fe88074b811 Mon Sep 17 00:00:00 2001 From: Wenqi Li Date: Wed, 15 Mar 2023 17:56:49 +0000 Subject: [PATCH 06/10] fixes codeqltests Signed-off-by: Wenqi Li --- .github/workflows/codeql-analysis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 1596db26b2..6df4857ec3 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -64,6 +64,7 @@ jobs: - name: Build run: | + python -m pip install -U pip wheel python -m pip install -r requirements-dev.txt BUILD_MONAI=1 ./runtests.sh --build From e06d8eadf08cc0fd4212daaf22fccdcebad8ab70 Mon Sep 17 00:00:00 2001 From: Wenqi Li Date: Thu, 16 Mar 2023 15:53:37 +0000 Subject: [PATCH 07/10] update based on comments Signed-off-by: Wenqi Li --- monai/data/image_writer.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/monai/data/image_writer.py b/monai/data/image_writer.py index 25b5d83226..e1a176d643 100644 --- a/monai/data/image_writer.py +++ b/monai/data/image_writer.py @@ -415,12 +415,10 @@ def set_data_array( spatial_ndim=kwargs.pop("spatial_ndim", 3), contiguous=kwargs.pop("contiguous", True), ) - if channel_dim is None: - self.channel_dim = -1 # after convert_to_channel_last the last dim is the channel + if self.data_obj is not None and len(self.data_obj.shape) <= _r: # squeezed end dims + self.channel_dim = None else: - self.channel_dim = ( - channel_dim if self.data_obj is not None and len(self.data_obj.shape) >= _r else None - ) # channel dim is at the end + self.channel_dim = -1 if channel_dim is None else channel_dim def set_metadata(self, meta_dict: Mapping | None = None, resample: bool = True, **options): """ From d9aaa7ebe20073170d31a9a5cc6212e3f819c9c5 Mon Sep 17 00:00:00 2001 From: Wenqi Li Date: Thu, 16 Mar 2023 17:43:59 +0000 Subject: [PATCH 08/10] update tests Signed-off-by: Wenqi Li --- monai/data/image_writer.py | 10 ++++++---- monai/transforms/io/array.py | 12 ++++++++++-- tests/test_itk_writer.py | 4 ++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/monai/data/image_writer.py b/monai/data/image_writer.py index e1a176d643..db0bfa96b8 100644 --- a/monai/data/image_writer.py +++ b/monai/data/image_writer.py @@ -407,7 +407,7 @@ def set_data_array( kwargs: keyword arguments passed to ``self.convert_to_channel_last``, currently support ``spatial_ndim`` and ``contiguous``, defauting to ``3`` and ``False`` respectively. """ - _r = len(data_array.shape) + n_chns = data_array.shape[channel_dim] if channel_dim is not None else 0 self.data_obj = self.convert_to_channel_last( data=data_array, channel_dim=channel_dim, @@ -415,10 +415,12 @@ def set_data_array( spatial_ndim=kwargs.pop("spatial_ndim", 3), contiguous=kwargs.pop("contiguous", True), ) - if self.data_obj is not None and len(self.data_obj.shape) <= _r: # squeezed end dims + self.channel_dim = -1 # in most cases, the data is set to channel last + if squeeze_end_dims and n_chns <= 1: # num_channel==1 squeezed self.channel_dim = None - else: - self.channel_dim = -1 if channel_dim is None else channel_dim + if not squeeze_end_dims and n_chns < 1: # originally no channel and convert_to_channel_last added a channel + self.channel_dim = None + self.data_obj = self.data_obj[..., 0] def set_metadata(self, meta_dict: Mapping | None = None, resample: bool = True, **options): """ diff --git a/monai/transforms/io/array.py b/monai/transforms/io/array.py index 92abafcec4..a21a070b15 100644 --- a/monai/transforms/io/array.py +++ b/monai/transforms/io/array.py @@ -40,6 +40,7 @@ PydicomReader, ) from monai.data.meta_tensor import MetaTensor +from monai.data.utils import is_no_channel from monai.transforms.transform import Transform from monai.transforms.utility.array import EnsureChannelFirst from monai.utils import GridSamplePadMode @@ -451,8 +452,15 @@ def __call__(self, img: torch.Tensor | np.ndarray, meta_data: dict | None = None meta_data = img.meta if isinstance(img, MetaTensor) else meta_data kw = self.fname_formatter(meta_data, self) filename = self.folder_layout.filename(**kw) - if meta_data and len(ensure_tuple(meta_data.get("spatial_shape", ()))) == len(img.shape): - self.data_kwargs["channel_dim"] = None + if meta_data: + meta_spatial_shape = ensure_tuple(meta_data.get("spatial_shape", ())) + if len(meta_spatial_shape) >= len(img.shape): + self.data_kwargs["channel_dim"] = None + elif is_no_channel(self.data_kwargs.get("channel_dim")): + warnings.warn( + f"data shape {img.shape} (with spatial shape {meta_spatial_shape}) " + f"but SaveImage `channel_dim` is set to {self.data_kwargs.get('channel_dim')} no channel." + ) err = [] for writer_cls in self.writers: diff --git a/tests/test_itk_writer.py b/tests/test_itk_writer.py index 75f848ec01..c9707b1b5a 100644 --- a/tests/test_itk_writer.py +++ b/tests/test_itk_writer.py @@ -60,8 +60,8 @@ def test_no_channel(self): writer.write(fname) output = np.asarray(itk.imread(fname)) - np.testing.assert_allclose(output.shape, (4, 3, 4)) - np.testing.assert_allclose(output[1, 1], (20, 21, 22, 23)) + np.testing.assert_allclose(output.shape, (4, 4, 3)) + np.testing.assert_allclose(output[1, 1], (5, 21, 37)) if __name__ == "__main__": From a7b889f78001da727b64ec94f44a2853069696c2 Mon Sep 17 00:00:00 2001 From: Wenqi Li Date: Thu, 16 Mar 2023 17:46:23 +0000 Subject: [PATCH 09/10] adds verified integration answers Signed-off-by: Wenqi Li --- tests/testing_data/integration_answers.py | 56 +++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/tests/testing_data/integration_answers.py b/tests/testing_data/integration_answers.py index b1f115e1d3..5f02052b61 100644 --- a/tests/testing_data/integration_answers.py +++ b/tests/testing_data/integration_answers.py @@ -14,6 +14,62 @@ import numpy as np EXPECTED_ANSWERS = [ + { # test answers for PyTorch 2.0 + "integration_segmentation_3d": { + "losses": [ + 0.5430086106061935, + 0.47010003924369814, + 0.4453376233577728, + 0.451901963353157, + 0.4398456811904907, + 0.43450237810611725, + ], + "best_metric": 0.9329540133476257, + "infer_metric": 0.9330471754074097, + "output_sums": [ + 0.14212507078546172, + 0.15199039602949577, + 0.15133471939291526, + 0.13967984811021827, + 0.18831614355832332, + 0.1694076821827231, + 0.14663931509271658, + 0.16788710637623733, + 0.1569452710008219, + 0.17907130698392254, + 0.16244092698688475, + 0.1679350345855819, + 0.14437674754879065, + 0.11355098478396568, + 0.161660275855964, + 0.20082478187698194, + 0.17575491677668853, + 0.0974593860605401, + 0.19366775441539907, + 0.20293016863409002, + 0.19610441127101647, + 0.20812173772459808, + 0.16184212006067655, + 0.13185211452732482, + 0.14824716961304257, + 0.14229818359602905, + 0.23141282114085215, + 0.1609268635938338, + 0.14825300029123678, + 0.10286266811772046, + 0.11873484714087054, + 0.1296615212510262, + 0.11386621034856693, + 0.15203351148564773, + 0.16300823766585265, + 0.1936726544485426, + 0.2227251185536394, + 0.18067789917505797, + 0.19005874127683337, + 0.07462121515702229, + ], + }, + }, { # test answers for PyTorch 1.12.1 "integration_classification_2d": { "losses": [0.776835828070428, 0.1615355300011149, 0.07492854832938523, 0.04591309238865877], From dd31ea22d2cf29e6cdc7faf376cda53f72bdac04 Mon Sep 17 00:00:00 2001 From: Wenqi Li Date: Thu, 16 Mar 2023 17:49:30 +0000 Subject: [PATCH 10/10] workaround https://github.com/Project-MONAI/MONAI/issues/6155 Signed-off-by: Wenqi Li --- tests/test_auto3dseg_ensemble.py | 2 +- tests/test_integration_autorunner.py | 2 +- tests/test_integration_gpu_customization.py | 2 +- tests/testing_data/integration_answers.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_auto3dseg_ensemble.py b/tests/test_auto3dseg_ensemble.py index 979ebf744b..0f41717a4a 100644 --- a/tests/test_auto3dseg_ensemble.py +++ b/tests/test_auto3dseg_ensemble.py @@ -70,7 +70,7 @@ @skip_if_quick -@SkipIfBeforePyTorchVersion((1, 10, 0)) +@SkipIfBeforePyTorchVersion((1, 13, 0)) @unittest.skipIf(not has_tb, "no tensorboard summary writer") class TestEnsembleBuilder(unittest.TestCase): def setUp(self) -> None: diff --git a/tests/test_integration_autorunner.py b/tests/test_integration_autorunner.py index 84583852ef..e6d088116b 100644 --- a/tests/test_integration_autorunner.py +++ b/tests/test_integration_autorunner.py @@ -69,7 +69,7 @@ @skip_if_quick -@SkipIfBeforePyTorchVersion((1, 9, 1)) +@SkipIfBeforePyTorchVersion((1, 13, 0)) @unittest.skipIf(not has_tb, "no tensorboard summary writer") class TestAutoRunner(unittest.TestCase): def setUp(self) -> None: diff --git a/tests/test_integration_gpu_customization.py b/tests/test_integration_gpu_customization.py index 4c8772ea50..1defb8545d 100644 --- a/tests/test_integration_gpu_customization.py +++ b/tests/test_integration_gpu_customization.py @@ -69,7 +69,7 @@ @skip_if_quick -@SkipIfBeforePyTorchVersion((1, 9, 1)) +@SkipIfBeforePyTorchVersion((1, 13, 0)) @unittest.skipIf(not has_tb, "no tensorboard summary writer") class TestEnsembleGpuCustomization(unittest.TestCase): def setUp(self) -> None: diff --git a/tests/testing_data/integration_answers.py b/tests/testing_data/integration_answers.py index 5f02052b61..559cbe8a39 100644 --- a/tests/testing_data/integration_answers.py +++ b/tests/testing_data/integration_answers.py @@ -68,7 +68,7 @@ 0.19005874127683337, 0.07462121515702229, ], - }, + } }, { # test answers for PyTorch 1.12.1 "integration_classification_2d": {