From 6f2dac0b5316896c06eabb86313dad93ac18a234 Mon Sep 17 00:00:00 2001 From: benediktjohannes Date: Tue, 13 Jan 2026 19:30:09 +0100 Subject: [PATCH 1/6] Update analyzer.py Fixes #8697 GPU memory leak by checking both image and label tensors for CUDA device Signed-off-by: benediktjohannes --- monai/auto3dseg/analyzer.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/monai/auto3dseg/analyzer.py b/monai/auto3dseg/analyzer.py index 8d662df83d..de0156f9fb 100644 --- a/monai/auto3dseg/analyzer.py +++ b/monai/auto3dseg/analyzer.py @@ -468,10 +468,13 @@ def __call__(self, data: Mapping[Hashable, MetaTensor]) -> dict[Hashable, MetaTe """ d: dict[Hashable, MetaTensor] = dict(data) start = time.time() - if isinstance(d[self.image_key], (torch.Tensor, MetaTensor)) and d[self.image_key].device.type == "cuda": - using_cuda = True - else: - using_cuda = False + image_tensor = d[self.image_key] + label_tensor = d[self.label_key] + using_cuda = ( + isinstance(image_tensor, (torch.Tensor, MetaTensor)) and image_tensor.device.type == "cuda" + ) or ( + isinstance(label_tensor, (torch.Tensor, MetaTensor)) and label_tensor.device.type == "cuda" + ) restore_grad_state = torch.is_grad_enabled() torch.set_grad_enabled(False) From 72522c1d499f58eb41ef91439cedce526f4e2ef9 Mon Sep 17 00:00:00 2001 From: benediktjohannes Date: Tue, 13 Jan 2026 19:47:42 +0100 Subject: [PATCH 2/6] Update analyzer.py Small refactoring (usage of local variable instead for performance) Signed-off-by: benediktjohannes --- monai/auto3dseg/analyzer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/monai/auto3dseg/analyzer.py b/monai/auto3dseg/analyzer.py index de0156f9fb..29e6684df7 100644 --- a/monai/auto3dseg/analyzer.py +++ b/monai/auto3dseg/analyzer.py @@ -478,8 +478,8 @@ def __call__(self, data: Mapping[Hashable, MetaTensor]) -> dict[Hashable, MetaTe restore_grad_state = torch.is_grad_enabled() torch.set_grad_enabled(False) - ndas: list[MetaTensor] = [d[self.image_key][i] for i in range(d[self.image_key].shape[0])] # type: ignore - ndas_label: MetaTensor = d[self.label_key].astype(torch.int16) # (H,W,D) + ndas: list[MetaTensor] = [image_tensor[i] for i in range(d[self.image_key].shape[0])] # type: ignore + ndas_label: MetaTensor = label_tensor.astype(torch.int16) # (H,W,D) if ndas_label.shape != ndas[0].shape: raise ValueError(f"Label shape {ndas_label.shape} is different from image shape {ndas[0].shape}") From f6b76dcdd3196a6b2039acf17d320e73969caa60 Mon Sep 17 00:00:00 2001 From: benediktjohannes Date: Tue, 13 Jan 2026 20:02:31 +0100 Subject: [PATCH 3/6] Update analyzer.py Another small refactoring Signed-off-by: benediktjohannes --- monai/auto3dseg/analyzer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monai/auto3dseg/analyzer.py b/monai/auto3dseg/analyzer.py index 29e6684df7..27b778d15b 100644 --- a/monai/auto3dseg/analyzer.py +++ b/monai/auto3dseg/analyzer.py @@ -478,7 +478,7 @@ def __call__(self, data: Mapping[Hashable, MetaTensor]) -> dict[Hashable, MetaTe restore_grad_state = torch.is_grad_enabled() torch.set_grad_enabled(False) - ndas: list[MetaTensor] = [image_tensor[i] for i in range(d[self.image_key].shape[0])] # type: ignore + ndas: list[MetaTensor] = [image_tensor[i] for i in range(image_tensor.shape[0])] # type: ignore ndas_label: MetaTensor = label_tensor.astype(torch.int16) # (H,W,D) if ndas_label.shape != ndas[0].shape: From b26f6becc116ee3a2e90c119a1e30b59382c36d1 Mon Sep 17 00:00:00 2001 From: benediktjohannes Date: Tue, 13 Jan 2026 20:24:13 +0100 Subject: [PATCH 4/6] Update analyzer.py Corrected type inconsistency Signed-off-by: benediktjohannes --- monai/auto3dseg/analyzer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monai/auto3dseg/analyzer.py b/monai/auto3dseg/analyzer.py index 27b778d15b..511ac390b9 100644 --- a/monai/auto3dseg/analyzer.py +++ b/monai/auto3dseg/analyzer.py @@ -485,7 +485,7 @@ def __call__(self, data: Mapping[Hashable, MetaTensor]) -> dict[Hashable, MetaTe raise ValueError(f"Label shape {ndas_label.shape} is different from image shape {ndas[0].shape}") nda_foregrounds: list[torch.Tensor] = [get_foreground_label(nda, ndas_label) for nda in ndas] - nda_foregrounds = [nda if nda.numel() > 0 else torch.Tensor([0]) for nda in nda_foregrounds] + nda_foregrounds = [nda if nda.numel() > 0 else MetaTensor([0.0]) for nda in nda_foregrounds] unique_label = unique(ndas_label) if isinstance(ndas_label, (MetaTensor, torch.Tensor)): From 6ac316255e0dce23ce22896d184ce446bc5ad9f0 Mon Sep 17 00:00:00 2001 From: benediktjohannes Date: Tue, 13 Jan 2026 20:41:47 +0100 Subject: [PATCH 5/6] Update analyzer.py Fixed type check and astype() usage Signed-off-by: benediktjohannes --- monai/auto3dseg/analyzer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/monai/auto3dseg/analyzer.py b/monai/auto3dseg/analyzer.py index 511ac390b9..c1b7f689e5 100644 --- a/monai/auto3dseg/analyzer.py +++ b/monai/auto3dseg/analyzer.py @@ -471,9 +471,9 @@ def __call__(self, data: Mapping[Hashable, MetaTensor]) -> dict[Hashable, MetaTe image_tensor = d[self.image_key] label_tensor = d[self.label_key] using_cuda = ( - isinstance(image_tensor, (torch.Tensor, MetaTensor)) and image_tensor.device.type == "cuda" + isinstance(image_tensor, MetaTensor) and image_tensor.device.type == "cuda" ) or ( - isinstance(label_tensor, (torch.Tensor, MetaTensor)) and label_tensor.device.type == "cuda" + isinstance(label_tensor, MetaTensor) and label_tensor.device.type == "cuda" ) restore_grad_state = torch.is_grad_enabled() torch.set_grad_enabled(False) From 090eb95ee6bc2f8436c0f45af4b5b803dc760a9b Mon Sep 17 00:00:00 2001 From: benediktjohannes Date: Tue, 13 Jan 2026 20:45:19 +0100 Subject: [PATCH 6/6] Update analyzer.py Using torch.Tensor instead of MetaTensor for broader CUDA detection Signed-off-by: benediktjohannes --- monai/auto3dseg/analyzer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/monai/auto3dseg/analyzer.py b/monai/auto3dseg/analyzer.py index c1b7f689e5..566824cd4b 100644 --- a/monai/auto3dseg/analyzer.py +++ b/monai/auto3dseg/analyzer.py @@ -471,9 +471,9 @@ def __call__(self, data: Mapping[Hashable, MetaTensor]) -> dict[Hashable, MetaTe image_tensor = d[self.image_key] label_tensor = d[self.label_key] using_cuda = ( - isinstance(image_tensor, MetaTensor) and image_tensor.device.type == "cuda" + isinstance(image_tensor, torch.Tensor) and image_tensor.device.type == "cuda" ) or ( - isinstance(label_tensor, MetaTensor) and label_tensor.device.type == "cuda" + isinstance(label_tensor, torch.Tensor) and label_tensor.device.type == "cuda" ) restore_grad_state = torch.is_grad_enabled() torch.set_grad_enabled(False)