Skip to content

Commit d8d887f

Browse files
authored
fixes integration test and 6354 (#6353)
- skip calls to torch.cuda.mem_get_info - fixes #6354 ### Types of changes <!--- Put an `x` in all the boxes that apply, and remove the not applicable items --> - [x] Non-breaking change (fix or new feature that would not break existing functionality). - [ ] Breaking change (fix or new feature that would cause existing functionality to change). - [ ] New tests added to cover the changes. - [ ] Integration tests passed locally by running `./runtests.sh -f -u --net --coverage`. - [x] Quick tests passed locally by running `./runtests.sh --quick --unittests --disttests`. - [x] In-line docstrings updated. - [ ] Documentation updated, tested `make html` command in the `docs/` folder. --------- Signed-off-by: Wenqi Li <wenqil@nvidia.com>
1 parent 1a55ba5 commit d8d887f

File tree

8 files changed

+37
-18
lines changed

8 files changed

+37
-18
lines changed

.github/workflows/pythonapp-gpu.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ jobs:
2525
- "PT110+CUDA111"
2626
- "PT112+CUDA118DOCKER"
2727
- "PT113+CUDA116"
28+
- "PT114+CUDA120DOCKER"
2829
include:
2930
# https://docs.nvidia.com/deeplearning/frameworks/pytorch-release-notes
3031
- environment: PT19+CUDA114DOCKER

monai/metrics/utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,18 +309,18 @@ def prepare_spacing(
309309
return list([spacing] * batch_size)
310310
elif isinstance(spacing, (Sequence, np.ndarray)):
311311
assert all(
312-
[isinstance(s, type(spacing[0])) for s in list(spacing)]
312+
isinstance(s, type(spacing[0])) for s in list(spacing)
313313
), "if `spacing` is a sequence, its elements should be of same type."
314314

315315
if isinstance(spacing[0], (Sequence, np.ndarray)):
316316
assert (
317317
len(spacing) == batch_size
318318
), "if `spacing` is a sequence of sequences, the outer sequence should have same length as batch size."
319319
assert all(
320-
[len(s) == img_dim for s in list(spacing)]
320+
len(s) == img_dim for s in list(spacing)
321321
), "each element of `spacing` list should either have same length as image dim."
322322
assert all(
323-
[isinstance(i, (int, float)) for s in list(spacing) for i in list(s)]
323+
isinstance(i, (int, float)) for s in list(spacing) for i in list(s)
324324
), "if `spacing` is a sequence of sequences or 2D np.ndarray, the elements should be integers or floats."
325325
return list(spacing)
326326
elif isinstance(spacing[0], (int, float)):

monai/networks/blocks/backbone_fpn_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ def _resnet_fpn_extractor(
155155
if trainable_layers == 5:
156156
layers_to_train.append("bn1")
157157
for name, parameter in backbone.named_parameters():
158-
if all([not name.startswith(layer) for layer in layers_to_train]):
158+
if all(not name.startswith(layer) for layer in layers_to_train):
159159
parameter.requires_grad_(False)
160160

161161
if extra_blocks is None:

monai/transforms/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,7 @@
624624
Fourier,
625625
allow_missing_keys_mode,
626626
attach_hook,
627+
check_non_lazy_pending_ops,
627628
compute_divisible_spatial_size,
628629
convert_applied_interp_mode,
629630
convert_pad_mode,

monai/transforms/croppad/array.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -780,8 +780,6 @@ def compute_bounding_box(self, img: torch.Tensor) -> tuple[np.ndarray, np.ndarra
780780
And adjust bounding box coords to be divisible by `k`.
781781
782782
"""
783-
if isinstance(img, MetaTensor) and img.pending_operations:
784-
warnings.warn("foreground computation may not be accurate if the image has pending operations.")
785783
box_start, box_end = generate_spatial_bounding_box(
786784
img, self.select_fn, self.channel_indices, self.margin, self.allow_smaller
787785
)
@@ -869,8 +867,6 @@ def __init__(
869867
self.centers: list[np.ndarray] = []
870868

871869
def randomize(self, weight_map: NdarrayOrTensor) -> None:
872-
if isinstance(weight_map, MetaTensor) and weight_map.pending_operations:
873-
warnings.warn("weight map has pending operations, the sampling may not be correct.")
874870
self.centers = weighted_patch_samples(
875871
spatial_size=self.spatial_size, w=weight_map[0], n_samples=self.num_samples, r_state=self.R
876872
) # using only the first channel as weight map
@@ -1015,10 +1011,6 @@ def randomize(
10151011
fg_indices_ = self.fg_indices if fg_indices is None else fg_indices
10161012
bg_indices_ = self.bg_indices if bg_indices is None else bg_indices
10171013
if fg_indices_ is None or bg_indices_ is None:
1018-
if isinstance(label, MetaTensor) and label.pending_operations:
1019-
warnings.warn("label has pending operations, the fg/bg indices may be incorrect.")
1020-
if isinstance(image, MetaTensor) and image.pending_operations:
1021-
warnings.warn("image has pending operations, the fg/bg indices may be incorrect.")
10221014
if label is None:
10231015
raise ValueError("label must be provided.")
10241016
fg_indices_, bg_indices_ = map_binary_to_indices(label, image, self.image_threshold)
@@ -1195,10 +1187,6 @@ def randomize(
11951187
) -> None:
11961188
indices_ = self.indices if indices is None else indices
11971189
if indices_ is None:
1198-
if isinstance(label, MetaTensor) and label.pending_operations:
1199-
warnings.warn("label has pending operations, the fg/bg indices may be incorrect.")
1200-
if isinstance(image, MetaTensor) and image.pending_operations:
1201-
warnings.warn("image has pending operations, the fg/bg indices may be incorrect.")
12021190
if label is None:
12031191
raise ValueError("label must not be None.")
12041192
indices_ = map_classes_to_indices(

monai/transforms/utils.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
"compute_divisible_spatial_size",
7676
"convert_applied_interp_mode",
7777
"copypaste_arrays",
78+
"check_non_lazy_pending_ops",
7879
"create_control_grid",
7980
"create_grid",
8081
"create_rotate",
@@ -294,6 +295,27 @@ def resize_center(img: np.ndarray, *resize_dims: int | None, fill_value: float =
294295
return img[srcslices]
295296

296297

298+
def check_non_lazy_pending_ops(
299+
input_array: NdarrayOrTensor, name: None | str = None, raise_error: bool = False
300+
) -> None:
301+
"""
302+
Check whether the input array has pending operations, raise an error or warn when it has.
303+
304+
Args:
305+
input_array: input array to be checked.
306+
name: an optional name to be included in the error message.
307+
raise_error: whether to raise an error, default to False, a warning message will be issued instead.
308+
"""
309+
if isinstance(input_array, monai.data.MetaTensor) and input_array.pending_operations:
310+
msg = (
311+
"The input image is a MetaTensor and has pending operations,\n"
312+
f"but the function {name or ''} assumes non-lazy input, result may be incorrect."
313+
)
314+
if raise_error:
315+
raise ValueError(msg)
316+
warnings.warn(msg)
317+
318+
297319
def map_binary_to_indices(
298320
label: NdarrayOrTensor, image: NdarrayOrTensor | None = None, image_threshold: float = 0.0
299321
) -> tuple[NdarrayOrTensor, NdarrayOrTensor]:
@@ -310,13 +332,14 @@ def map_binary_to_indices(
310332
image_threshold: if enabled `image`, use ``image > image_threshold`` to
311333
determine the valid image content area and select background only in this area.
312334
"""
313-
335+
check_non_lazy_pending_ops(label, name="map_binary_to_indices")
314336
# Prepare fg/bg indices
315337
if label.shape[0] > 1:
316338
label = label[1:] # for One-Hot format data, remove the background channel
317339
label_flat = ravel(any_np_pt(label, 0)) # in case label has multiple dimensions
318340
fg_indices = nonzero(label_flat)
319341
if image is not None:
342+
check_non_lazy_pending_ops(image, name="map_binary_to_indices")
320343
img_flat = ravel(any_np_pt(image > image_threshold, 0))
321344
img_flat, *_ = convert_to_dst_type(img_flat, label, dtype=bool)
322345
bg_indices = nonzero(img_flat & ~label_flat)
@@ -357,8 +380,10 @@ def map_classes_to_indices(
357380
Default is None, no subsampling.
358381
359382
"""
383+
check_non_lazy_pending_ops(label, name="map_classes_to_indices")
360384
img_flat: NdarrayOrTensor | None = None
361385
if image is not None:
386+
check_non_lazy_pending_ops(image, name="map_classes_to_indices")
362387
img_flat = ravel((image > image_threshold).any(0))
363388

364389
# assuming the first dimension is channel
@@ -410,6 +435,7 @@ def weighted_patch_samples(
410435
a list of `n_samples` N-D integers representing the spatial sampling location of patches.
411436
412437
"""
438+
check_non_lazy_pending_ops(w, name="weighted_patch_samples")
413439
if w is None:
414440
raise ValueError("w must be an ND array, got None.")
415441
if r_state is None:
@@ -937,6 +963,7 @@ def generate_spatial_bounding_box(
937963
allow_smaller: when computing box size with `margin`, whether allow the image size to be smaller
938964
than box size, default to `True`.
939965
"""
966+
check_non_lazy_pending_ops(img, name="generate_spatial_bounding_box")
940967
spatial_size = img.shape[1:]
941968
data = img[list(ensure_tuple(channel_indices))] if channel_indices is not None else img
942969
data = select_fn(data).any(0)
@@ -1175,6 +1202,7 @@ def get_extreme_points(
11751202
Raises:
11761203
ValueError: When the input image does not have any foreground pixel.
11771204
"""
1205+
check_non_lazy_pending_ops(img, name="get_extreme_points")
11781206
if rand_state is None:
11791207
rand_state = np.random.random.__self__ # type: ignore
11801208
indices = where(img != background)

tests/runner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ def get_default_pattern(loader):
131131
cases.append(f"tests.{test_module}")
132132
else:
133133
print(f"monai test runner: excluding tests.{test_module}")
134+
print(cases)
134135
tests = unittest.TestLoader().loadTestsFromNames(cases)
135136
discovery_time = pc.total_time
136137
print(f"time to discover tests: {discovery_time}s, total cases: {tests.countTestCases()}.")

tests/test_integration_gpu_customization.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767

6868

6969
@skip_if_quick
70-
@SkipIfBeforePyTorchVersion((1, 9, 1))
70+
@SkipIfBeforePyTorchVersion((1, 11, 1)) # module 'torch.cuda' has no attribute 'mem_get_info'
7171
@unittest.skipIf(not has_tb, "no tensorboard summary writer")
7272
class TestEnsembleGpuCustomization(unittest.TestCase):
7373
def setUp(self) -> None:

0 commit comments

Comments
 (0)